blob: 33a472af367d7341e4104e34c613c268ce973462 [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
Deva Ramasubramanianeb819322014-07-17 14:23:35 -070042#define __STDC_FORMAT_MACROS
43#include <inttypes.h>
44
Shalaj Jain273b3e02012-06-22 19:08:03 -070045#include <string.h>
46#include <pthread.h>
47#include <sys/prctl.h>
48#include <stdlib.h>
49#include <unistd.h>
50#include <errno.h>
51#include "omx_vdec.h"
52#include <fcntl.h>
53#include <limits.h>
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -070054#include <stdlib.h>
Arun Menonbdb80b02013-08-12 17:45:54 -070055#include <media/hardware/HardwareAPI.h>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080056#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070057
58#ifndef _ANDROID_
59#include <sys/ioctl.h>
60#include <sys/mman.h>
61#endif //_ANDROID_
62
63#ifdef _ANDROID_
64#include <cutils/properties.h>
65#undef USE_EGL_IMAGE_GPU
66#endif
67
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070068#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070069
70#ifdef _ANDROID_
71#include "DivXDrmDecrypt.h"
72#endif //_ANDROID_
73
Arun Menon45346052013-11-13 12:40:08 -080074#ifdef METADATA_FOR_DYNAMIC_MODE
Arun Menon9af783f2013-10-22 12:57:14 -070075#include "QComOMXMetadata.h"
76#endif
77
Shalaj Jain273b3e02012-06-22 19:08:03 -070078#ifdef USE_EGL_IMAGE_GPU
79#include <EGL/egl.h>
80#include <EGL/eglQCOM.h>
81#define EGL_BUFFER_HANDLE_QCOM 0x4F00
82#define EGL_BUFFER_OFFSET_QCOM 0x4F01
83#endif
Vinay Kalia21649b32013-03-18 17:28:07 -070084
Jayasena Sangaraboina51230642013-08-21 18:02:13 -070085#define BUFFER_LOG_LOC "/data/misc/media"
86
Shalaj Jain273b3e02012-06-22 19:08:03 -070087#ifdef OUTPUT_EXTRADATA_LOG
88FILE *outputExtradataFile;
Deva Ramasubramanianee6f1f42014-01-31 12:49:18 -080089char output_extradata_filename [] = "/data/misc/extradata";
Shalaj Jain273b3e02012-06-22 19:08:03 -070090#endif
91
92#define DEFAULT_FPS 30
Shalaj Jain273b3e02012-06-22 19:08:03 -070093#define MAX_SUPPORTED_FPS 120
Deepak Vermaa2efdb12013-12-26 12:30:05 +053094#define DEFAULT_WIDTH_ALIGNMENT 128
95#define DEFAULT_HEIGHT_ALIGNMENT 32
Shalaj Jain273b3e02012-06-22 19:08:03 -070096
97#define VC1_SP_MP_START_CODE 0xC5000000
98#define VC1_SP_MP_START_CODE_MASK 0xFF000000
99#define VC1_AP_SEQ_START_CODE 0x0F010000
100#define VC1_STRUCT_C_PROFILE_MASK 0xF0
101#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
102#define VC1_SIMPLE_PROFILE 0
103#define VC1_MAIN_PROFILE 1
104#define VC1_ADVANCE_PROFILE 3
105#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
106#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
107#define VC1_STRUCT_C_LEN 4
108#define VC1_STRUCT_C_POS 8
109#define VC1_STRUCT_A_POS 12
110#define VC1_STRUCT_B_POS 24
111#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700112#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700113
114#define MEM_DEVICE "/dev/ion"
115#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
116
117#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700118extern "C" {
119#include<utils/Log.h>
120}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700121#endif//_ANDROID_
122
Vinay Kalia53fa6832012-10-11 17:55:30 -0700123#define SZ_4K 0x1000
124#define SZ_1M 0x100000
125
Shalaj Jain273b3e02012-06-22 19:08:03 -0700126#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
127#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 -0700128#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
129
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800130#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jia Meng3a3c6492013-12-19 17:16:52 +0800131#define DEFAULT_CONCEAL_COLOR "32896" //0x8080, black by default
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700132
133int debug_level = PRIO_ERROR;
134
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530135static OMX_U32 maxSmoothStreamingWidth = 1920;
136static OMX_U32 maxSmoothStreamingHeight = 1088;
Praveen Chavancf924182013-12-06 23:16:23 -0800137
Shalaj Jain273b3e02012-06-22 19:08:03 -0700138void* async_message_thread (void *input)
139{
Arun Menon906de572013-06-18 17:01:40 -0700140 OMX_BUFFERHEADERTYPE *buffer;
141 struct v4l2_plane plane[VIDEO_MAX_PLANES];
142 struct pollfd pfd;
143 struct v4l2_buffer v4l2_buf;
144 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
145 struct v4l2_event dqevent;
146 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
147 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
148 pfd.fd = omx->drv_ctx.video_driver_fd;
149 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700150 DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
Arun Menon906de572013-06-18 17:01:40 -0700151 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
152 while (1) {
153 rc = poll(&pfd, 1, POLL_TIMEOUT);
154 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700155 DEBUG_PRINT_ERROR("Poll timedout");
Arun Menon906de572013-06-18 17:01:40 -0700156 break;
157 } else if (rc < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700158 DEBUG_PRINT_ERROR("Error while polling: %d", rc);
Arun Menon906de572013-06-18 17:01:40 -0700159 break;
160 }
161 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
162 struct vdec_msginfo vdec_msg;
163 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
164 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
165 v4l2_buf.length = omx->drv_ctx.num_planes;
166 v4l2_buf.m.planes = plane;
167 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
168 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
169 vdec_msg.status_code=VDEC_S_SUCCESS;
170 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
171 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
172 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
173 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
174 (uint64_t)v4l2_buf.timestamp.tv_usec;
175 if (vdec_msg.msgdata.output_frame.len) {
176 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
177 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
178 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
179 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +0530180 vdec_msg.msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
181 vdec_msg.msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
Arun Menon906de572013-06-18 17:01:40 -0700182 }
183 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700184 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700185 break;
186 }
187 }
188 }
189 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
190 struct vdec_msginfo vdec_msg;
191 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
192 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
193 v4l2_buf.length = 1;
194 v4l2_buf.m.planes = plane;
195 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
196 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
197 vdec_msg.status_code=VDEC_S_SUCCESS;
198 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
199 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700200 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700201 break;
202 }
203 }
204 }
205 if (pfd.revents & POLLPRI) {
206 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
207 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
208 struct vdec_msginfo vdec_msg;
209 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
210 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700211 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved insufficient");
Arun Menon906de572013-06-18 17:01:40 -0700212 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700213 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700214 break;
215 }
216 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
217 struct vdec_msginfo vdec_msg;
218 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
219 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700220 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700221 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700222 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700223 break;
224 }
225 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
226 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700227 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700228 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700229 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700230 break;
231 }
232 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700233 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700234 break;
Deepak Verma24720fb2014-01-29 16:57:40 +0530235 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
236 struct vdec_msginfo vdec_msg;
237 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
238 vdec_msg.status_code=VDEC_S_SUCCESS;
239 DEBUG_PRINT_ERROR("HW Overload received");
240 if (omx->async_message_process(input,&vdec_msg) < 0) {
241 DEBUG_PRINT_HIGH("async_message_thread Exited");
242 break;
243 }
Arun Menon906de572013-06-18 17:01:40 -0700244 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
245 struct vdec_msginfo vdec_msg;
Jia Meng1e236c82014-04-03 10:54:39 +0800246 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR;
247 vdec_msg.status_code = VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700248 DEBUG_PRINT_HIGH("SYS Error Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700249 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700250 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700251 break;
252 }
Arun Menon45346052013-11-13 12:40:08 -0800253 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
Arun Menonbdb80b02013-08-12 17:45:54 -0700254 unsigned int *ptr = (unsigned int *)dqevent.u.data;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700255 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700256 omx->buf_ref_remove(ptr[0], ptr[1]);
257 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
258 unsigned int *ptr = (unsigned int *)dqevent.u.data;
259 struct vdec_msginfo vdec_msg;
260
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700261 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700262
263 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
264 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
265 v4l2_buf.length = omx->drv_ctx.num_planes;
266 v4l2_buf.m.planes = plane;
267 v4l2_buf.index = ptr[5];
268 v4l2_buf.flags = 0;
269
270 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
271 vdec_msg.status_code = VDEC_S_SUCCESS;
272 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
273 vdec_msg.msgdata.output_frame.len = 0;
274 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
275 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
276 (uint64_t)ptr[4];
277 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700278 DEBUG_PRINT_HIGH("async_message_thread Exitedn");
Arun Menonbdb80b02013-08-12 17:45:54 -0700279 break;
280 }
281 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700282 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700283 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
Arun Menon906de572013-06-18 17:01:40 -0700284 continue;
285 }
286 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700287 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700288 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700289 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700290}
291
292void* message_thread(void *input)
293{
Arun Menon906de572013-06-18 17:01:40 -0700294 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
295 unsigned char id;
296 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700297
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700298 DEBUG_PRINT_HIGH("omx_vdec: message thread start");
Arun Menon906de572013-06-18 17:01:40 -0700299 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
300 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700301
Arun Menon906de572013-06-18 17:01:40 -0700302 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700303
Arun Menon906de572013-06-18 17:01:40 -0700304 if (0 == n) {
305 break;
306 }
307
308 if (1 == n) {
309 omx->process_event_cb(omx, id);
310 }
311 if ((n < 0) && (errno != EINTR)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700312 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
Arun Menon906de572013-06-18 17:01:40 -0700313 break;
314 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700315 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700316 DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700317 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700318}
319
320void post_message(omx_vdec *omx, unsigned char id)
321{
Arun Menon906de572013-06-18 17:01:40 -0700322 int ret_value;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700323 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
Arun Menon906de572013-06-18 17:01:40 -0700324 ret_value = write(omx->m_pipe_out, &id, 1);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700325 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700326}
327
328// omx_cmd_queue destructor
329omx_vdec::omx_cmd_queue::~omx_cmd_queue()
330{
Arun Menon906de572013-06-18 17:01:40 -0700331 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700332}
333
334// omx cmd queue constructor
335omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
336{
337 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
338}
339
340// omx cmd queue insert
341bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
342{
Arun Menon906de572013-06-18 17:01:40 -0700343 bool ret = true;
344 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
345 m_q[m_write].id = id;
346 m_q[m_write].param1 = p1;
347 m_q[m_write].param2 = p2;
348 m_write++;
349 m_size ++;
350 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
351 m_write = 0;
352 }
353 } else {
354 ret = false;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700355 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700356 }
Arun Menon906de572013-06-18 17:01:40 -0700357 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700358}
359
360// omx cmd queue pop
361bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
362{
Arun Menon906de572013-06-18 17:01:40 -0700363 bool ret = true;
364 if (m_size > 0) {
365 *id = m_q[m_read].id;
366 *p1 = m_q[m_read].param1;
367 *p2 = m_q[m_read].param2;
368 // Move the read pointer ahead
369 ++m_read;
370 --m_size;
371 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
372 m_read = 0;
373 }
374 } else {
375 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700376 }
Arun Menon906de572013-06-18 17:01:40 -0700377 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700378}
379
380// Retrieve the first mesg type in the queue
381unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
382{
383 return m_q[m_read].id;
384}
385
386#ifdef _ANDROID_
387omx_vdec::ts_arr_list::ts_arr_list()
388{
Arun Menon906de572013-06-18 17:01:40 -0700389 //initialize timestamps array
390 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700391}
392omx_vdec::ts_arr_list::~ts_arr_list()
393{
Arun Menon906de572013-06-18 17:01:40 -0700394 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700395}
396
397bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
398{
Arun Menon906de572013-06-18 17:01:40 -0700399 bool ret = true;
400 bool duplicate_ts = false;
401 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700402
Arun Menon906de572013-06-18 17:01:40 -0700403 //insert at the first available empty location
404 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
405 if (!m_ts_arr_list[idx].valid) {
406 //found invalid or empty entry, save timestamp
407 m_ts_arr_list[idx].valid = true;
408 m_ts_arr_list[idx].timestamp = ts;
409 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
410 ts, idx);
411 break;
412 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700413 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700414
Arun Menon906de572013-06-18 17:01:40 -0700415 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
416 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
417 ret = false;
418 }
419 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700420}
421
422bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
423{
Arun Menon906de572013-06-18 17:01:40 -0700424 bool ret = true;
425 int min_idx = -1;
426 OMX_TICKS min_ts = 0;
427 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700428
Arun Menon906de572013-06-18 17:01:40 -0700429 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700430
Arun Menon906de572013-06-18 17:01:40 -0700431 if (m_ts_arr_list[idx].valid) {
432 //found valid entry, save index
433 if (min_idx < 0) {
434 //first valid entry
435 min_ts = m_ts_arr_list[idx].timestamp;
436 min_idx = idx;
437 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
438 min_ts = m_ts_arr_list[idx].timestamp;
439 min_idx = idx;
440 }
441 }
442
Shalaj Jain273b3e02012-06-22 19:08:03 -0700443 }
444
Arun Menon906de572013-06-18 17:01:40 -0700445 if (min_idx < 0) {
446 //no valid entries found
447 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
448 ts = 0;
449 ret = false;
450 } else {
451 ts = m_ts_arr_list[min_idx].timestamp;
452 m_ts_arr_list[min_idx].valid = false;
453 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
454 ts, min_idx);
455 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700456
Arun Menon906de572013-06-18 17:01:40 -0700457 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700458
459}
460
461
462bool omx_vdec::ts_arr_list::reset_ts_list()
463{
Arun Menon906de572013-06-18 17:01:40 -0700464 bool ret = true;
465 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700466
Arun Menon906de572013-06-18 17:01:40 -0700467 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
468 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
469 m_ts_arr_list[idx].valid = false;
470 }
471 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700472}
473#endif
474
475// factory function executed by the core to create instances
476void *get_omx_component_factory_fn(void)
477{
Arun Menon906de572013-06-18 17:01:40 -0700478 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700479}
480
481#ifdef _ANDROID_
482#ifdef USE_ION
483VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700484 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700485{
Arun Menon906de572013-06-18 17:01:40 -0700486 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700487}
488#else
489VideoHeap::VideoHeap(int fd, size_t size, void* base)
490{
491 // dup file descriptor, map once, use pmem
492 init(dup(fd), base, size, 0 , MEM_DEVICE);
493}
494#endif
495#endif // _ANDROID_
496/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700497 FUNCTION
498 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700499
Arun Menon906de572013-06-18 17:01:40 -0700500 DESCRIPTION
501 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700502
Arun Menon906de572013-06-18 17:01:40 -0700503 PARAMETERS
504 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700505
Arun Menon906de572013-06-18 17:01:40 -0700506 RETURN VALUE
507 None.
508 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800509omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700510 m_state(OMX_StateInvalid),
511 m_app_data(NULL),
512 m_inp_mem_ptr(NULL),
513 m_out_mem_ptr(NULL),
Arun Menon906de572013-06-18 17:01:40 -0700514 input_flush_progress (false),
515 output_flush_progress (false),
516 input_use_buffer (false),
517 output_use_buffer (false),
518 ouput_egl_buffers(false),
519 m_use_output_pmem(OMX_FALSE),
520 m_out_mem_region_smi(OMX_FALSE),
521 m_out_pvt_entry_pmem(OMX_FALSE),
522 pending_input_buffers(0),
523 pending_output_buffers(0),
524 m_out_bm_count(0),
525 m_inp_bm_count(0),
526 m_inp_bPopulated(OMX_FALSE),
527 m_out_bPopulated(OMX_FALSE),
528 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700529#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700530 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700531#endif
Arun Menon906de572013-06-18 17:01:40 -0700532 m_inp_bEnabled(OMX_TRUE),
533 m_out_bEnabled(OMX_TRUE),
534 m_in_alloc_cnt(0),
535 m_platform_list(NULL),
536 m_platform_entry(NULL),
537 m_pmem_info(NULL),
538 arbitrary_bytes (true),
539 psource_frame (NULL),
540 pdest_frame (NULL),
541 m_inp_heap_ptr (NULL),
542 m_phdr_pmem_ptr(NULL),
543 m_heap_inp_bm_count (0),
544 codec_type_parse ((codec_type)0),
545 first_frame_meta (true),
546 frame_count (0),
547 nal_count (0),
548 nal_length(0),
549 look_ahead_nal (false),
550 first_frame(0),
551 first_buffer(NULL),
552 first_frame_size (0),
553 m_device_file_ptr(NULL),
554 m_vc1_profile((vc1_profile_type)0),
Arun Menon906de572013-06-18 17:01:40 -0700555 h264_last_au_ts(LLONG_MAX),
556 h264_last_au_flags(0),
Surajit Podderd2644d52013-08-28 17:59:06 +0530557 m_disp_hor_size(0),
558 m_disp_vert_size(0),
Arun Menon906de572013-06-18 17:01:40 -0700559 prev_ts(LLONG_MAX),
560 rst_prev_ts(true),
561 frm_int(0),
Arun Menon906de572013-06-18 17:01:40 -0700562 in_reconfig(false),
563 m_display_id(NULL),
564 h264_parser(NULL),
565 client_extradata(0),
566 m_reject_avc_1080p_mp (0),
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +0530567 m_other_extradata(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700568#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700569 m_enable_android_native_buffers(OMX_FALSE),
570 m_use_android_native_buffers(OMX_FALSE),
571 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700572#endif
Arun Menon906de572013-06-18 17:01:40 -0700573 m_desc_buffer_ptr(NULL),
574 secure_mode(false),
Surajit Podderd2644d52013-08-28 17:59:06 +0530575 m_profile(0),
vivek mehtaa75c69f2014-01-10 21:50:37 -0800576 client_set_fps(false),
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -0700577 m_last_rendered_TS(-1),
578 m_queued_codec_config_count(0)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700579{
Arun Menon906de572013-06-18 17:01:40 -0700580 /* Assumption is that , to begin with , we have all the frames with decoder */
581 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700582 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700583#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700584 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700585 property_get("vidc.debug.level", property_value, "0");
586 debug_level = atoi(property_value);
587 property_value[0] = '\0';
588
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700589 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
590
Arun Menon906de572013-06-18 17:01:40 -0700591 property_get("vidc.dec.debug.perf", property_value, "0");
592 perf_flag = atoi(property_value);
593 if (perf_flag) {
594 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
595 dec_time.start();
596 proc_frms = latency = 0;
597 }
598 prev_n_filled_len = 0;
599 property_value[0] = '\0';
600 property_get("vidc.dec.debug.ts", property_value, "0");
601 m_debug_timestamp = atoi(property_value);
602 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
603 if (m_debug_timestamp) {
604 time_stamp_dts.set_timestamp_reorder_mode(true);
605 time_stamp_dts.enable_debug_print(true);
606 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700607
Arun Menon906de572013-06-18 17:01:40 -0700608 property_value[0] = '\0';
609 property_get("vidc.dec.debug.concealedmb", property_value, "0");
610 m_debug_concealedmb = atoi(property_value);
611 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
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.profile.check", property_value, "0");
615 m_reject_avc_1080p_mp = atoi(property_value);
616 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530617
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700618 property_value[0] = '\0';
619 property_get("vidc.dec.log.in", property_value, "0");
620 m_debug.in_buffer_log = atoi(property_value);
621
622 property_value[0] = '\0';
623 property_get("vidc.dec.log.out", property_value, "0");
624 m_debug.out_buffer_log = atoi(property_value);
625 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
626
627 property_value[0] = '\0';
628 property_get("vidc.log.loc", property_value, "");
629 if (*property_value)
630 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
vivek mehta79cff222014-01-22 12:17:07 -0800631
632 property_value[0] = '\0';
633 property_get("vidc.dec.120fps.enabled", property_value, "0");
634
635 //if this feature is not enabled then reset this value -ve
636 if(atoi(property_value)) {
637 DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
638 m_last_rendered_TS = 0;
639 }
640
Shalaj Jain273b3e02012-06-22 19:08:03 -0700641#endif
Arun Menon906de572013-06-18 17:01:40 -0700642 memset(&m_cmp,0,sizeof(m_cmp));
643 memset(&m_cb,0,sizeof(m_cb));
644 memset (&drv_ctx,0,sizeof(drv_ctx));
645 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
646 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
647 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +0530648 memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
Arun Menon906de572013-06-18 17:01:40 -0700649 m_demux_entries = 0;
650 msg_thread_id = 0;
651 async_thread_id = 0;
652 msg_thread_created = false;
653 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700654#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700655 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700656#endif
Arun Menon906de572013-06-18 17:01:40 -0700657 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Maheshwar Ajjad2df2182013-10-24 19:20:34 +0530658 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -0700659 drv_ctx.timestamp_adjust = false;
660 drv_ctx.video_driver_fd = -1;
661 m_vendor_config.pData = NULL;
662 pthread_mutex_init(&m_lock, NULL);
663 pthread_mutex_init(&c_lock, NULL);
664 sem_init(&m_cmd_lock,0,0);
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -0700665 sem_init(&m_safe_flush, 0, 0);
Arun Menon906de572013-06-18 17:01:40 -0700666 streaming[CAPTURE_PORT] =
667 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700668#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700669 char extradata_value[PROPERTY_VALUE_MAX] = {0};
670 property_get("vidc.dec.debug.extradata", extradata_value, "0");
671 m_debug_extradata = atoi(extradata_value);
672 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700673#endif
Arun Menon906de572013-06-18 17:01:40 -0700674 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
675 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700676 dynamic_buf_mode = false;
677 out_dynamic_list = NULL;
Praveen Chavane78460c2013-12-06 23:16:04 -0800678 is_down_scalar_enabled = false;
Praveen Chavancf924182013-12-06 23:16:23 -0800679 m_smoothstreaming_mode = false;
680 m_smoothstreaming_width = 0;
681 m_smoothstreaming_height = 0;
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530682 is_q6_platform = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700683}
684
Vinay Kalia85793762012-06-14 19:12:34 -0700685static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700686 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
687 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
688 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700689 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
690 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
Arun Menon906de572013-06-18 17:01:40 -0700691 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
Jia Meng1e236c82014-04-03 10:54:39 +0800692 V4L2_EVENT_MSM_VIDC_SYS_ERROR,
693 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD
Vinay Kalia85793762012-06-14 19:12:34 -0700694};
695
696static OMX_ERRORTYPE subscribe_to_events(int fd)
697{
Arun Menon906de572013-06-18 17:01:40 -0700698 OMX_ERRORTYPE eRet = OMX_ErrorNone;
699 struct v4l2_event_subscription sub;
700 int array_sz = sizeof(event_type)/sizeof(int);
701 int i,rc;
702 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700703 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700704 return OMX_ErrorBadParameter;
705 }
Vinay Kalia85793762012-06-14 19:12:34 -0700706
Arun Menon906de572013-06-18 17:01:40 -0700707 for (i = 0; i < array_sz; ++i) {
708 memset(&sub, 0, sizeof(sub));
709 sub.type = event_type[i];
710 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
711 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700712 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700713 break;
714 }
715 }
716 if (i < array_sz) {
717 for (--i; i >=0 ; i--) {
718 memset(&sub, 0, sizeof(sub));
719 sub.type = event_type[i];
720 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
721 if (rc)
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700722 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700723 }
724 eRet = OMX_ErrorNotImplemented;
725 }
726 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700727}
728
729
730static OMX_ERRORTYPE unsubscribe_to_events(int fd)
731{
Arun Menon906de572013-06-18 17:01:40 -0700732 OMX_ERRORTYPE eRet = OMX_ErrorNone;
733 struct v4l2_event_subscription sub;
734 int array_sz = sizeof(event_type)/sizeof(int);
735 int i,rc;
736 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700737 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700738 return OMX_ErrorBadParameter;
739 }
Vinay Kalia85793762012-06-14 19:12:34 -0700740
Arun Menon906de572013-06-18 17:01:40 -0700741 for (i = 0; i < array_sz; ++i) {
742 memset(&sub, 0, sizeof(sub));
743 sub.type = event_type[i];
744 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
745 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700746 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700747 break;
748 }
749 }
750 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700751}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700752
753/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700754 FUNCTION
755 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700756
Arun Menon906de572013-06-18 17:01:40 -0700757 DESCRIPTION
758 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700759
Arun Menon906de572013-06-18 17:01:40 -0700760 PARAMETERS
761 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700762
Arun Menon906de572013-06-18 17:01:40 -0700763 RETURN VALUE
764 None.
765 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700766omx_vdec::~omx_vdec()
767{
Arun Menon906de572013-06-18 17:01:40 -0700768 m_pmem_info = NULL;
769 struct v4l2_decoder_cmd dec;
770 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
771 if (m_pipe_in) close(m_pipe_in);
772 if (m_pipe_out) close(m_pipe_out);
773 m_pipe_in = -1;
774 m_pipe_out = -1;
775 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
776 if (msg_thread_created)
777 pthread_join(msg_thread_id,NULL);
778 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
779 dec.cmd = V4L2_DEC_CMD_STOP;
780 if (drv_ctx.video_driver_fd >=0 ) {
781 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700782 DEBUG_PRINT_ERROR("STOP Command failed");
Arun Menon906de572013-06-18 17:01:40 -0700783 }
784 if (async_thread_created)
785 pthread_join(async_thread_id,NULL);
786 unsubscribe_to_events(drv_ctx.video_driver_fd);
787 close(drv_ctx.video_driver_fd);
788 pthread_mutex_destroy(&m_lock);
789 pthread_mutex_destroy(&c_lock);
790 sem_destroy(&m_cmd_lock);
791 if (perf_flag) {
792 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
793 dec_time.end();
794 }
795 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700796}
797
Arun Menon906de572013-06-18 17:01:40 -0700798int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
799{
800 struct v4l2_requestbuffers bufreq;
801 int rc = 0;
802 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
803 bufreq.memory = V4L2_MEMORY_USERPTR;
804 bufreq.count = 0;
805 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
806 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530807 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
808 bufreq.memory = V4L2_MEMORY_USERPTR;
809 bufreq.count = 0;
810 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
811 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700812 }
813 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700814}
815
Shalaj Jain273b3e02012-06-22 19:08:03 -0700816/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700817 FUNCTION
818 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700819
Arun Menon906de572013-06-18 17:01:40 -0700820 DESCRIPTION
821 IL Client callbacks are generated through this routine. The decoder
822 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700823
Arun Menon906de572013-06-18 17:01:40 -0700824 PARAMETERS
825 ctxt -- Context information related to the self.
826 id -- Event identifier. This could be any of the following:
827 1. Command completion event
828 2. Buffer done callback event
829 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700830
Arun Menon906de572013-06-18 17:01:40 -0700831 RETURN VALUE
832 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700833
Arun Menon906de572013-06-18 17:01:40 -0700834 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700835void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
836{
Arun Menon906de572013-06-18 17:01:40 -0700837 signed p1; // Parameter - 1
838 signed p2; // Parameter - 2
839 unsigned ident;
840 unsigned qsize=0; // qsize
841 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700842
Arun Menon906de572013-06-18 17:01:40 -0700843 if (!pThis) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700844 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
Arun Menon906de572013-06-18 17:01:40 -0700845 __func__);
846 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700847 }
848
Arun Menon906de572013-06-18 17:01:40 -0700849 // Protect the shared queue data structure
850 do {
851 /*Read the message id's from the queue*/
852 pthread_mutex_lock(&pThis->m_lock);
853 qsize = pThis->m_cmd_q.m_size;
854 if (qsize) {
855 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700856 }
Arun Menon906de572013-06-18 17:01:40 -0700857
858 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
859 qsize = pThis->m_ftb_q.m_size;
860 if (qsize) {
861 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
862 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700863 }
Arun Menon906de572013-06-18 17:01:40 -0700864
865 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
866 qsize = pThis->m_etb_q.m_size;
867 if (qsize) {
868 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
869 }
870 }
871 pthread_mutex_unlock(&pThis->m_lock);
872
873 /*process message if we have one*/
874 if (qsize > 0) {
875 id = ident;
876 switch (id) {
877 case OMX_COMPONENT_GENERATE_EVENT:
878 if (pThis->m_cb.EventHandler) {
879 switch (p1) {
880 case OMX_CommandStateSet:
881 pThis->m_state = (OMX_STATETYPE) p2;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700882 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
Arun Menon906de572013-06-18 17:01:40 -0700883 pThis->m_state);
884 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
885 OMX_EventCmdComplete, p1, p2, NULL);
886 break;
887
888 case OMX_EventError:
889 if (p2 == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700890 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
Arun Menon906de572013-06-18 17:01:40 -0700891 pThis->m_state = (OMX_STATETYPE) p2;
892 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
893 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
894 } else if (p2 == OMX_ErrorHardware) {
895 pThis->omx_report_error();
896 } else {
897 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
898 OMX_EventError, p2, (OMX_U32)NULL, NULL );
899 }
900 break;
901
902 case OMX_CommandPortDisable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700903 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700904 if (BITMASK_PRESENT(&pThis->m_flags,
905 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
906 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
907 break;
908 }
909 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
910 OMX_ERRORTYPE eRet = OMX_ErrorNone;
911 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
912 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700913 DEBUG_PRINT_HIGH("Failed to release output buffers");
Arun Menon906de572013-06-18 17:01:40 -0700914 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
915 pThis->in_reconfig = false;
916 if (eRet != OMX_ErrorNone) {
917 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
918 pThis->omx_report_error();
919 break;
920 }
921 }
922 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
923 OMX_EventCmdComplete, p1, p2, NULL );
924 break;
925 case OMX_CommandPortEnable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700926 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700927 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
928 OMX_EventCmdComplete, p1, p2, NULL );
929 break;
930
931 default:
932 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
933 OMX_EventCmdComplete, p1, p2, NULL );
934 break;
935
936 }
937 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700938 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Arun Menon906de572013-06-18 17:01:40 -0700939 }
940 break;
941 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
942 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
943 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700944 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
Arun Menon906de572013-06-18 17:01:40 -0700945 pThis->omx_report_error ();
946 }
947 break;
Jia Meng1e236c82014-04-03 10:54:39 +0800948 case OMX_COMPONENT_GENERATE_ETB: {
949 OMX_ERRORTYPE iret;
950 iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
951 if (iret == OMX_ErrorInsufficientResources) {
952 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
953 pThis->omx_report_hw_overload ();
954 } else if (iret != OMX_ErrorNone) {
955 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
956 pThis->omx_report_error ();
957 }
Arun Menon906de572013-06-18 17:01:40 -0700958 }
959 break;
960
961 case OMX_COMPONENT_GENERATE_FTB:
962 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
963 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700964 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700965 pThis->omx_report_error ();
966 }
967 break;
968
969 case OMX_COMPONENT_GENERATE_COMMAND:
970 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
971 (OMX_U32)p2,(OMX_PTR)NULL);
972 break;
973
974 case OMX_COMPONENT_GENERATE_EBD:
975
976 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700977 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700978 pThis->omx_report_error ();
979 } else {
980 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
Arun Menon906de572013-06-18 17:01:40 -0700981 pThis->time_stamp_dts.remove_time_stamp(
982 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
983 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
984 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -0700985 }
Deva Ramasubramanian02b0d882014-04-03 14:58:50 -0700986
Arun Menon906de572013-06-18 17:01:40 -0700987 if ( pThis->empty_buffer_done(&pThis->m_cmp,
988 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700989 DEBUG_PRINT_ERROR("empty_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700990 pThis->omx_report_error ();
991 }
Arun Menon906de572013-06-18 17:01:40 -0700992 }
993 break;
994 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
995 int64_t *timestamp = (int64_t *)p1;
996 if (p1) {
997 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
998 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
999 ?true:false);
1000 free(timestamp);
1001 }
1002 }
1003 break;
1004 case OMX_COMPONENT_GENERATE_FBD:
1005 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001006 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
Arun Menon906de572013-06-18 17:01:40 -07001007 pThis->omx_report_error ();
1008 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
1009 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001010 DEBUG_PRINT_ERROR("fill_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -07001011 pThis->omx_report_error ();
1012 }
1013 break;
1014
1015 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001016 DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001017 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001018 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001019 } else {
1020 pThis->execute_input_flush();
1021 if (pThis->m_cb.EventHandler) {
1022 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001023 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
Arun Menon906de572013-06-18 17:01:40 -07001024 pThis->omx_report_error ();
1025 } else {
1026 /*Check if we need generate event for Flush done*/
1027 if (BITMASK_PRESENT(&pThis->m_flags,
1028 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
1029 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001030 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
Arun Menon906de572013-06-18 17:01:40 -07001031 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1032 OMX_EventCmdComplete,OMX_CommandFlush,
1033 OMX_CORE_INPUT_PORT_INDEX,NULL );
1034 }
1035 if (BITMASK_PRESENT(&pThis->m_flags,
1036 OMX_COMPONENT_IDLE_PENDING)) {
1037 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001038 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
Arun Menon906de572013-06-18 17:01:40 -07001039 pThis->omx_report_error ();
1040 } else {
1041 pThis->streaming[OUTPUT_PORT] = false;
1042 }
1043 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001044 DEBUG_PRINT_LOW("Input flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001045 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1046 OMX_COMPONENT_GENERATE_STOP_DONE);
1047 }
1048 }
1049 }
1050 } else {
1051 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1052 }
1053 }
1054 break;
1055
1056 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001057 DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001058 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001059 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001060 } else {
1061 pThis->execute_output_flush();
1062 if (pThis->m_cb.EventHandler) {
1063 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001064 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
Arun Menon906de572013-06-18 17:01:40 -07001065 pThis->omx_report_error ();
1066 } else {
1067 /*Check if we need generate event for Flush done*/
1068 if (BITMASK_PRESENT(&pThis->m_flags,
1069 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001070 DEBUG_PRINT_LOW("Notify Output Flush done");
Arun Menon906de572013-06-18 17:01:40 -07001071 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1072 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1073 OMX_EventCmdComplete,OMX_CommandFlush,
1074 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1075 }
1076 if (BITMASK_PRESENT(&pThis->m_flags,
1077 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001078 DEBUG_PRINT_LOW("Internal flush complete");
Arun Menon906de572013-06-18 17:01:40 -07001079 BITMASK_CLEAR (&pThis->m_flags,
1080 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1081 if (BITMASK_PRESENT(&pThis->m_flags,
1082 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1083 pThis->post_event(OMX_CommandPortDisable,
1084 OMX_CORE_OUTPUT_PORT_INDEX,
1085 OMX_COMPONENT_GENERATE_EVENT);
1086 BITMASK_CLEAR (&pThis->m_flags,
1087 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
Praneeth Paladugub52072a2013-08-23 13:54:43 -07001088 BITMASK_CLEAR (&pThis->m_flags,
1089 OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Arun Menon906de572013-06-18 17:01:40 -07001090
1091 }
1092 }
1093
1094 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1095 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001096 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
Arun Menon906de572013-06-18 17:01:40 -07001097 pThis->omx_report_error ();
1098 break;
1099 }
1100 pThis->streaming[CAPTURE_PORT] = false;
1101 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001102 DEBUG_PRINT_LOW("Output flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001103 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1104 OMX_COMPONENT_GENERATE_STOP_DONE);
1105 }
1106 }
1107 }
1108 } else {
1109 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1110 }
1111 }
1112 break;
1113
1114 case OMX_COMPONENT_GENERATE_START_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001115 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001116
1117 if (pThis->m_cb.EventHandler) {
1118 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001119 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
Arun Menon906de572013-06-18 17:01:40 -07001120 pThis->omx_report_error ();
1121 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001122 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001123 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001124 DEBUG_PRINT_LOW("Move to executing");
Arun Menon906de572013-06-18 17:01:40 -07001125 // Send the callback now
1126 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1127 pThis->m_state = OMX_StateExecuting;
1128 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1129 OMX_EventCmdComplete,OMX_CommandStateSet,
1130 OMX_StateExecuting, NULL);
1131 } else if (BITMASK_PRESENT(&pThis->m_flags,
1132 OMX_COMPONENT_PAUSE_PENDING)) {
1133 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1134 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001135 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
Arun Menon906de572013-06-18 17:01:40 -07001136 pThis->omx_report_error ();
1137 }
1138 }
1139 }
1140 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001141 DEBUG_PRINT_LOW("Event Handler callback is NULL");
Arun Menon906de572013-06-18 17:01:40 -07001142 }
1143 break;
1144
1145 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001146 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001147 if (pThis->m_cb.EventHandler) {
1148 if (p2 != VDEC_S_SUCCESS) {
1149 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1150 pThis->omx_report_error ();
1151 } else {
1152 pThis->complete_pending_buffer_done_cbs();
1153 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001154 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
Arun Menon906de572013-06-18 17:01:40 -07001155 //Send the callback now
1156 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1157 pThis->m_state = OMX_StatePause;
1158 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1159 OMX_EventCmdComplete,OMX_CommandStateSet,
1160 OMX_StatePause, NULL);
1161 }
1162 }
1163 } else {
1164 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1165 }
1166
1167 break;
1168
1169 case OMX_COMPONENT_GENERATE_RESUME_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001170 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001171 if (pThis->m_cb.EventHandler) {
1172 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001173 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
Arun Menon906de572013-06-18 17:01:40 -07001174 pThis->omx_report_error ();
1175 } else {
1176 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001177 DEBUG_PRINT_LOW("Moving the decoder to execute state");
Arun Menon906de572013-06-18 17:01:40 -07001178 // Send the callback now
1179 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1180 pThis->m_state = OMX_StateExecuting;
1181 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1182 OMX_EventCmdComplete,OMX_CommandStateSet,
1183 OMX_StateExecuting,NULL);
1184 }
1185 }
1186 } else {
1187 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1188 }
1189
1190 break;
1191
1192 case OMX_COMPONENT_GENERATE_STOP_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001193 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001194 if (pThis->m_cb.EventHandler) {
1195 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001196 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
Arun Menon906de572013-06-18 17:01:40 -07001197 pThis->omx_report_error ();
1198 } else {
1199 pThis->complete_pending_buffer_done_cbs();
1200 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001201 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001202 // Send the callback now
1203 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1204 pThis->m_state = OMX_StateIdle;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001205 DEBUG_PRINT_LOW("Move to Idle State");
Arun Menon906de572013-06-18 17:01:40 -07001206 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1207 OMX_EventCmdComplete,OMX_CommandStateSet,
1208 OMX_StateIdle,NULL);
1209 }
1210 }
1211 } else {
1212 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1213 }
1214
1215 break;
1216
1217 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
Arun Menon906de572013-06-18 17:01:40 -07001218 if (p2 == OMX_IndexParamPortDefinition) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301219 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07001220 pThis->in_reconfig = true;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301221
1222 } else if (p2 == OMX_IndexConfigCommonOutputCrop) {
1223 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301224
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301225 /* Check if resolution is changed in smooth streaming mode */
1226 if (pThis->m_smoothstreaming_mode &&
1227 (pThis->framesize.nWidth !=
1228 pThis->drv_ctx.video_resolution.frame_width) ||
1229 (pThis->framesize.nHeight !=
1230 pThis->drv_ctx.video_resolution.frame_height)) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301231
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301232 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
1233 pThis->framesize.nWidth,
1234 pThis->framesize.nHeight,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301235 pThis->drv_ctx.video_resolution.frame_width,
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301236 pThis->drv_ctx.video_resolution.frame_height);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301237
1238 /* Update new resolution */
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301239 pThis->framesize.nWidth =
1240 pThis->drv_ctx.video_resolution.frame_width;
1241 pThis->framesize.nHeight =
1242 pThis->drv_ctx.video_resolution.frame_height;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301243
1244 /* Update C2D with new resolution */
1245 if (!pThis->client_buffers.update_buffer_req()) {
1246 DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
1247 }
1248 }
1249
1250 /* Update new crop information */
1251 pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
1252 pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
1253 pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
1254 pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
1255
1256 /* Validate the new crop information */
1257 if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
1258 pThis->drv_ctx.video_resolution.frame_width) {
1259
1260 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
1261 pThis->rectangle.nLeft, pThis->rectangle.nWidth,
1262 pThis->drv_ctx.video_resolution.frame_width);
1263 pThis->rectangle.nLeft = 0;
1264
1265 if (pThis->rectangle.nWidth >
1266 pThis->drv_ctx.video_resolution.frame_width) {
1267
1268 DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
1269 pThis->rectangle.nWidth,
1270 pThis->drv_ctx.video_resolution.frame_width);
1271 pThis->rectangle.nWidth =
1272 pThis->drv_ctx.video_resolution.frame_width;
1273 }
1274 }
1275 if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
1276 pThis->drv_ctx.video_resolution.frame_height) {
1277
1278 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
1279 pThis->rectangle.nTop, pThis->rectangle.nHeight,
1280 pThis->drv_ctx.video_resolution.frame_height);
1281 pThis->rectangle.nTop = 0;
1282
1283 if (pThis->rectangle.nHeight >
1284 pThis->drv_ctx.video_resolution.frame_height) {
1285
1286 DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
1287 pThis->rectangle.nHeight,
1288 pThis->drv_ctx.video_resolution.frame_height);
1289 pThis->rectangle.nHeight =
1290 pThis->drv_ctx.video_resolution.frame_height;
1291 }
1292 }
1293 DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
1294 pThis->rectangle.nLeft, pThis->rectangle.nTop,
1295 pThis->rectangle.nWidth, pThis->rectangle.nHeight);
1296 } else {
1297 DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
1298 break;
Arun Menon906de572013-06-18 17:01:40 -07001299 }
1300 if (pThis->m_cb.EventHandler) {
1301 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1302 OMX_EventPortSettingsChanged, p1, p2, NULL );
1303 } else {
1304 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1305 }
Arun Menon906de572013-06-18 17:01:40 -07001306 break;
1307
1308 case OMX_COMPONENT_GENERATE_EOS_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001309 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001310 if (pThis->m_cb.EventHandler) {
1311 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1312 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1313 } else {
1314 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1315 }
1316 pThis->prev_ts = LLONG_MAX;
1317 pThis->rst_prev_ts = true;
1318 break;
1319
1320 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001321 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
Arun Menon906de572013-06-18 17:01:40 -07001322 pThis->omx_report_error ();
1323 break;
1324
1325 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001326 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
Arun Menon906de572013-06-18 17:01:40 -07001327 pThis->omx_report_unsupported_setting();
1328 break;
1329
Deepak Verma24720fb2014-01-29 16:57:40 +05301330 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
1331 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
1332 pThis->omx_report_hw_overload();
1333 break;
1334
Arun Menon906de572013-06-18 17:01:40 -07001335 default:
1336 break;
1337 }
1338 }
1339 pthread_mutex_lock(&pThis->m_lock);
1340 qsize = pThis->m_cmd_q.m_size;
1341 if (pThis->m_state != OMX_StatePause)
1342 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1343 pthread_mutex_unlock(&pThis->m_lock);
1344 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001345
1346}
1347
Vinay Kaliab9e98102013-04-02 19:31:43 -07001348int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001349{
Arun Menon906de572013-06-18 17:01:40 -07001350 int format_changed = 0;
Surajit Podderd2644d52013-08-28 17:59:06 +05301351 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1352 (width != (int)drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001353 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
Arun Menon906de572013-06-18 17:01:40 -07001354 width, drv_ctx.video_resolution.frame_width,
1355 height,drv_ctx.video_resolution.frame_height);
1356 format_changed = 1;
1357 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001358 drv_ctx.video_resolution.frame_height = height;
1359 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001360 drv_ctx.video_resolution.scan_lines = scan_lines;
1361 drv_ctx.video_resolution.stride = stride;
Pushkaraj Patil41588352014-02-25 20:51:34 +05301362 if(!is_down_scalar_enabled) {
1363 rectangle.nLeft = 0;
1364 rectangle.nTop = 0;
1365 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1366 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
1367 }
Arun Menon906de572013-06-18 17:01:40 -07001368 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001369}
1370
Arun Menon6836ba02013-02-19 20:37:40 -08001371OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1372{
Arun Menon906de572013-06-18 17:01:40 -07001373 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1374 OMX_MAX_STRINGNAME_SIZE) &&
1375 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1376 m_decoder_capability.max_width = 1280;
1377 m_decoder_capability.max_height = 720;
1378 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1379 }
Arun Menon888aa852013-05-30 11:24:42 -07001380
Arun Menon906de572013-06-18 17:01:40 -07001381 if ((drv_ctx.video_resolution.frame_width *
1382 drv_ctx.video_resolution.frame_height >
1383 m_decoder_capability.max_width *
1384 m_decoder_capability.max_height) ||
1385 (drv_ctx.video_resolution.frame_width*
1386 drv_ctx.video_resolution.frame_height <
1387 m_decoder_capability.min_width *
1388 m_decoder_capability.min_height)) {
1389 DEBUG_PRINT_ERROR(
1390 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1391 drv_ctx.video_resolution.frame_width,
1392 drv_ctx.video_resolution.frame_height,
1393 m_decoder_capability.min_width,
1394 m_decoder_capability.min_height,
1395 m_decoder_capability.max_width,
1396 m_decoder_capability.max_height);
1397 return OMX_ErrorUnsupportedSetting;
1398 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001399 DEBUG_PRINT_HIGH("video session supported");
Arun Menon906de572013-06-18 17:01:40 -07001400 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001401}
1402
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001403int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1404{
1405 if (m_debug.in_buffer_log && !m_debug.infile) {
1406 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1407 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1408 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1409 }
1410 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1411 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); }
1412 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1413 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
1414 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1415 }
1416 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
1417 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1418 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1419 }
1420 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1421 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1422 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1423 }
1424 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1425 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1426 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1427 }
1428 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1429 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1430 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1431 }
1432 m_debug.infile = fopen (m_debug.infile_name, "ab");
1433 if (!m_debug.infile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001434 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001435 m_debug.infile_name[0] = '\0';
1436 return -1;
1437 }
1438 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1439 struct ivf_file_header {
1440 OMX_U8 signature[4]; //='DKIF';
1441 OMX_U8 version ; //= 0;
1442 OMX_U8 headersize ; //= 32;
1443 OMX_U32 FourCC;
1444 OMX_U8 width;
1445 OMX_U8 height;
1446 OMX_U32 rate;
1447 OMX_U32 scale;
1448 OMX_U32 length;
1449 OMX_U8 unused[4];
1450 } file_header;
1451
1452 memset((void *)&file_header,0,sizeof(file_header));
1453 file_header.signature[0] = 'D';
1454 file_header.signature[1] = 'K';
1455 file_header.signature[2] = 'I';
1456 file_header.signature[3] = 'F';
1457 file_header.version = 0;
1458 file_header.headersize = 32;
1459 file_header.FourCC = 0x30385056;
1460 fwrite((const char *)&file_header,
1461 sizeof(file_header),1,m_debug.infile);
1462 }
1463 }
1464 if (m_debug.infile && buffer_addr && buffer_len) {
1465 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1466 struct vp8_ivf_frame_header {
1467 OMX_U32 framesize;
1468 OMX_U32 timestamp_lo;
1469 OMX_U32 timestamp_hi;
1470 } vp8_frame_header;
1471 vp8_frame_header.framesize = buffer_len;
1472 /* Currently FW doesn't use timestamp values */
1473 vp8_frame_header.timestamp_lo = 0;
1474 vp8_frame_header.timestamp_hi = 0;
1475 fwrite((const char *)&vp8_frame_header,
1476 sizeof(vp8_frame_header),1,m_debug.infile);
1477 }
1478 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1479 }
1480 return 0;
1481}
1482
1483int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1484 if (m_debug.out_buffer_log && !m_debug.outfile) {
1485 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1486 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1487 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1488 if (!m_debug.outfile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001489 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001490 m_debug.outfile_name[0] = '\0';
1491 return -1;
1492 }
1493 }
1494 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1495 int buf_index = buffer - m_out_mem_ptr;
1496 int stride = drv_ctx.video_resolution.stride;
1497 int scanlines = drv_ctx.video_resolution.scan_lines;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301498 if (m_smoothstreaming_mode) {
1499 stride = drv_ctx.video_resolution.frame_width;
1500 scanlines = drv_ctx.video_resolution.frame_height;
1501 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
1502 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
1503 }
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001504 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1505 unsigned i;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301506 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
1507 drv_ctx.video_resolution.frame_width,
1508 drv_ctx.video_resolution.frame_height, stride, scanlines);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001509 int bytes_written = 0;
1510 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1511 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1512 temp += stride;
1513 }
1514 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1515 int stride_c = stride;
1516 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1517 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1518 temp += stride_c;
1519 }
1520 }
1521 return 0;
1522}
1523
Shalaj Jain273b3e02012-06-22 19:08:03 -07001524/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001525 FUNCTION
1526 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001527
Arun Menon906de572013-06-18 17:01:40 -07001528 DESCRIPTION
1529 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001530
Arun Menon906de572013-06-18 17:01:40 -07001531 PARAMETERS
1532 ctxt -- Context information related to the self.
1533 id -- Event identifier. This could be any of the following:
1534 1. Command completion event
1535 2. Buffer done callback event
1536 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001537
Arun Menon906de572013-06-18 17:01:40 -07001538 RETURN VALUE
1539 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001540
Arun Menon906de572013-06-18 17:01:40 -07001541 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001542OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1543{
1544
Arun Menon906de572013-06-18 17:01:40 -07001545 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1546 struct v4l2_fmtdesc fdesc;
1547 struct v4l2_format fmt;
1548 struct v4l2_requestbuffers bufreq;
1549 struct v4l2_control control;
1550 struct v4l2_frmsizeenum frmsize;
1551 unsigned int alignment = 0,buffer_size = 0;
1552 int fds[2];
1553 int r,ret=0;
1554 bool codec_ambiguous = false;
Praveen Chavan00ec0ce2015-05-18 09:44:20 -07001555 OMX_STRING device_name = (OMX_STRING)"/dev/video32";
Jia Meng3a3c6492013-12-19 17:16:52 +08001556 char property_value[PROPERTY_VALUE_MAX] = {0};
Sachin Shahc82a18f2013-03-29 14:45:38 -07001557
1558#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001559 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001560 property_get("ro.board.platform", platform_name, "0");
1561 if (!strncmp(platform_name, "msm8610", 7)) {
Balamurugan Alagarsamy1693e592015-07-23 19:19:05 +05301562 device_name = (OMX_STRING)"/dev/video34";
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301563 is_q6_platform = true;
1564 maxSmoothStreamingWidth = 1280;
1565 maxSmoothStreamingHeight = 720;
Arun Menon906de572013-06-18 17:01:40 -07001566 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001567#endif
1568
Arun Menon906de572013-06-18 17:01:40 -07001569 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1570 struct v4l2_control control;
1571 secure_mode = true;
1572 arbitrary_bytes = false;
1573 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301574 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
1575 OMX_MAX_STRINGNAME_SIZE)){
1576 secure_mode = true;
1577 arbitrary_bytes = false;
1578 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
Arun Menon906de572013-06-18 17:01:40 -07001579 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001580
Arun Menon906de572013-06-18 17:01:40 -07001581 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001582
Balamurugan Alagarsamy1693e592015-07-23 19:19:05 +05301583 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open device %s returned fd %d",
1584 device_name, drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001585
Arun Menon906de572013-06-18 17:01:40 -07001586 if (drv_ctx.video_driver_fd == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001587 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
Arun Menon906de572013-06-18 17:01:40 -07001588 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1589 close(0);
1590 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001591
Arun Menon906de572013-06-18 17:01:40 -07001592 if (drv_ctx.video_driver_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001593 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
Arun Menon906de572013-06-18 17:01:40 -07001594 return OMX_ErrorInsufficientResources;
1595 }
1596 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1597 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001598
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001599 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001600 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001601 async_thread_created = true;
1602 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1603 }
1604 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001605 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
Arun Menon906de572013-06-18 17:01:40 -07001606 async_thread_created = false;
1607 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001608 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001609
Shalaj Jain273b3e02012-06-22 19:08:03 -07001610#ifdef OUTPUT_EXTRADATA_LOG
Deva Ramasubramanianee6f1f42014-01-31 12:49:18 -08001611 outputExtradataFile = fopen (output_extradata_filename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001612#endif
1613
Arun Menon906de572013-06-18 17:01:40 -07001614 // Copy the role information which provides the decoder kind
1615 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001616
Arun Menon906de572013-06-18 17:01:40 -07001617 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1618 OMX_MAX_STRINGNAME_SIZE)) {
1619 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1620 OMX_MAX_STRINGNAME_SIZE);
1621 drv_ctx.timestamp_adjust = true;
1622 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1623 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1624 output_capability=V4L2_PIX_FMT_MPEG4;
1625 /*Initialize Start Code for MPEG4*/
1626 codec_type_parse = CODEC_TYPE_MPEG4;
1627 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001628 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1629 OMX_MAX_STRINGNAME_SIZE)) {
1630 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1631 OMX_MAX_STRINGNAME_SIZE);
1632 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1633 output_capability = V4L2_PIX_FMT_MPEG2;
1634 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1635 /*Initialize Start Code for MPEG2*/
1636 codec_type_parse = CODEC_TYPE_MPEG2;
1637 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001638 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1639 OMX_MAX_STRINGNAME_SIZE)) {
1640 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001641 DEBUG_PRINT_LOW("H263 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001642 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1643 eCompressionFormat = OMX_VIDEO_CodingH263;
1644 output_capability = V4L2_PIX_FMT_H263;
1645 codec_type_parse = CODEC_TYPE_H263;
1646 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001647 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1648 OMX_MAX_STRINGNAME_SIZE)) {
1649 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001650 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001651 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1652 output_capability = V4L2_PIX_FMT_DIVX_311;
1653 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1654 codec_type_parse = CODEC_TYPE_DIVX;
1655 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001656
Arun Menon906de572013-06-18 17:01:40 -07001657 eRet = createDivxDrmContext();
1658 if (eRet != OMX_ErrorNone) {
1659 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1660 return eRet;
1661 }
1662 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1663 OMX_MAX_STRINGNAME_SIZE)) {
1664 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001665 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001666 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1667 output_capability = V4L2_PIX_FMT_DIVX;
1668 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1669 codec_type_parse = CODEC_TYPE_DIVX;
1670 codec_ambiguous = true;
1671 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001672
Arun Menon906de572013-06-18 17:01:40 -07001673 eRet = createDivxDrmContext();
1674 if (eRet != OMX_ErrorNone) {
1675 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1676 return eRet;
1677 }
1678 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1679 OMX_MAX_STRINGNAME_SIZE)) {
1680 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001681 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001682 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1683 output_capability = V4L2_PIX_FMT_DIVX;
1684 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1685 codec_type_parse = CODEC_TYPE_DIVX;
1686 codec_ambiguous = true;
1687 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001688
Arun Menon906de572013-06-18 17:01:40 -07001689 eRet = createDivxDrmContext();
1690 if (eRet != OMX_ErrorNone) {
1691 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1692 return eRet;
1693 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001694
Arun Menon906de572013-06-18 17:01:40 -07001695 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1696 OMX_MAX_STRINGNAME_SIZE)) {
1697 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1698 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1699 output_capability=V4L2_PIX_FMT_H264;
1700 eCompressionFormat = OMX_VIDEO_CodingAVC;
1701 codec_type_parse = CODEC_TYPE_H264;
1702 m_frame_parser.init_start_codes (codec_type_parse);
1703 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001704 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1705 OMX_MAX_STRINGNAME_SIZE)) {
1706 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1707 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1708 eCompressionFormat = OMX_VIDEO_CodingWMV;
1709 codec_type_parse = CODEC_TYPE_VC1;
1710 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1711 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001712 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1713 OMX_MAX_STRINGNAME_SIZE)) {
1714 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1715 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1716 eCompressionFormat = OMX_VIDEO_CodingWMV;
1717 codec_type_parse = CODEC_TYPE_VC1;
1718 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1719 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001720 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1721 OMX_MAX_STRINGNAME_SIZE)) {
1722 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1723 output_capability=V4L2_PIX_FMT_VP8;
Praveen Chavan76b71c32014-07-10 18:10:51 -07001724 eCompressionFormat = OMX_VIDEO_CodingVP8;
Arun Menon906de572013-06-18 17:01:40 -07001725 codec_type_parse = CODEC_TYPE_VP8;
1726 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001727
Arun Menon906de572013-06-18 17:01:40 -07001728 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001729 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07001730 eRet = OMX_ErrorInvalidComponentName;
1731 }
Arun Menon906de572013-06-18 17:01:40 -07001732 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001733
Arun Menon906de572013-06-18 17:01:40 -07001734 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001735 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1736 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1737 if (!client_buffers.set_color_format(dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001738 DEBUG_PRINT_ERROR("Setting color format failed");
Vinay Kaliada4f4422013-01-09 10:45:03 -08001739 eRet = OMX_ErrorInsufficientResources;
1740 }
1741
Arun Menon906de572013-06-18 17:01:40 -07001742 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001743
Arun Menon906de572013-06-18 17:01:40 -07001744 struct v4l2_capability cap;
1745 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1746 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001747 DEBUG_PRINT_ERROR("Failed to query capabilities");
Arun Menon906de572013-06-18 17:01:40 -07001748 /*TODO: How to handle this case */
1749 } else {
1750 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001751 " version = %d, capabilities = %x", cap.driver, cap.card,
Arun Menon906de572013-06-18 17:01:40 -07001752 cap.bus_info, cap.version, cap.capabilities);
1753 }
1754 ret=0;
1755 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1756 fdesc.index=0;
1757 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001758 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001759 fdesc.pixelformat, fdesc.flags);
1760 fdesc.index++;
1761 }
1762 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1763 fdesc.index=0;
1764 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001765
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001766 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001767 fdesc.pixelformat, fdesc.flags);
1768 fdesc.index++;
1769 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001770 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001771 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1772 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1773 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1774 fmt.fmt.pix_mp.pixelformat = output_capability;
1775 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1776 if (ret) {
1777 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001778 DEBUG_PRINT_ERROR("Failed to set format on output port");
Arun Menon906de572013-06-18 17:01:40 -07001779 return OMX_ErrorInsufficientResources;
1780 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001781 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001782 if (codec_ambiguous) {
1783 if (output_capability == V4L2_PIX_FMT_DIVX) {
1784 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001785
Arun Menon906de572013-06-18 17:01:40 -07001786 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1787 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1788 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1789 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1790 } else {
1791 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1792 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001793
Arun Menon906de572013-06-18 17:01:40 -07001794 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1795 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1796 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001797 DEBUG_PRINT_ERROR("Failed to set divx version");
Arun Menon906de572013-06-18 17:01:40 -07001798 }
1799 } else {
1800 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1801 }
1802 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001803
Jia Meng3a3c6492013-12-19 17:16:52 +08001804 property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
1805 m_conceal_color= atoi(property_value);
1806 DEBUG_PRINT_HIGH("trying to set 0x%x as conceal color\n",m_conceal_color);
1807 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
1808 control.value = m_conceal_color;
1809 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1810 if (ret) {
1811 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
1812 }
1813
Arun Menon906de572013-06-18 17:01:40 -07001814 //Get the hardware capabilities
1815 memset((void *)&frmsize,0,sizeof(frmsize));
1816 frmsize.index = 0;
1817 frmsize.pixel_format = output_capability;
1818 ret = ioctl(drv_ctx.video_driver_fd,
1819 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1820 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001821 DEBUG_PRINT_ERROR("Failed to get framesizes");
Arun Menon906de572013-06-18 17:01:40 -07001822 return OMX_ErrorHardware;
1823 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001824
Arun Menon906de572013-06-18 17:01:40 -07001825 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1826 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1827 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1828 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1829 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1830 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001831
Arun Menon906de572013-06-18 17:01:40 -07001832 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1833 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1834 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1835 fmt.fmt.pix_mp.pixelformat = capture_capability;
1836 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1837 if (ret) {
1838 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001839 DEBUG_PRINT_ERROR("Failed to set format on capture port");
Arun Menon906de572013-06-18 17:01:40 -07001840 }
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301841 memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
1842 framesize.nWidth = drv_ctx.video_resolution.frame_width;
1843 framesize.nHeight = drv_ctx.video_resolution.frame_height;
1844
1845 memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
1846 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1847 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
1848
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001849 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001850 if (secure_mode) {
1851 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1852 control.value = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001853 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001854 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1855 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001856 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001857 return OMX_ErrorInsufficientResources;
1858 }
1859 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001860
Arun Menon906de572013-06-18 17:01:40 -07001861 /*Get the Buffer requirements for input and output ports*/
1862 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1863 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1864 if (secure_mode) {
1865 drv_ctx.op_buf.alignment=SZ_1M;
1866 drv_ctx.ip_buf.alignment=SZ_1M;
1867 } else {
1868 drv_ctx.op_buf.alignment=SZ_4K;
1869 drv_ctx.ip_buf.alignment=SZ_4K;
1870 }
1871 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1872 drv_ctx.extradata = 0;
1873 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1874 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1875 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1876 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1877 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001878
Vinay Kalia5713bb32013-01-16 18:39:59 -08001879 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001880#ifdef DEFAULT_EXTRADATA
Arun Menonf8908a62013-12-20 17:36:21 -08001881 if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
1882 OMX_MAX_STRINGNAME_SIZE) && (eRet == OMX_ErrorNone))
1883 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001884#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001885 eRet=get_buffer_req(&drv_ctx.ip_buf);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001886 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
Vinay Kalia5713bb32013-01-16 18:39:59 -08001887 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001888 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1889 if (m_frame_parser.mutils == NULL) {
1890 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001891
Arun Menon906de572013-06-18 17:01:40 -07001892 if (m_frame_parser.mutils == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001893 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001894 eRet = OMX_ErrorInsufficientResources;
1895 } else {
1896 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1897 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1898 h264_scratch.nFilledLen = 0;
1899 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001900
Arun Menon906de572013-06-18 17:01:40 -07001901 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001902 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001903 return OMX_ErrorInsufficientResources;
1904 }
1905 m_frame_parser.mutils->initialize_frame_checking_environment();
1906 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1907 }
1908 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001909
Arun Menon906de572013-06-18 17:01:40 -07001910 h264_parser = new h264_stream_parser();
1911 if (!h264_parser) {
1912 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1913 eRet = OMX_ErrorInsufficientResources;
1914 }
1915 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001916
Arun Menon906de572013-06-18 17:01:40 -07001917 if (pipe(fds)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001918 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001919 eRet = OMX_ErrorInsufficientResources;
1920 } else {
1921 int temp1[2];
1922 if (fds[0] == 0 || fds[1] == 0) {
1923 if (pipe (temp1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001924 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001925 return OMX_ErrorInsufficientResources;
1926 }
1927 //close (fds[0]);
1928 //close (fds[1]);
1929 fds[0] = temp1 [0];
1930 fds[1] = temp1 [1];
1931 }
1932 m_pipe_in = fds[0];
1933 m_pipe_out = fds[1];
1934 msg_thread_created = true;
1935 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001936
Arun Menon906de572013-06-18 17:01:40 -07001937 if (r < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001938 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001939 msg_thread_created = false;
1940 eRet = OMX_ErrorInsufficientResources;
1941 }
1942 }
1943 }
1944
1945 if (eRet != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001946 DEBUG_PRINT_ERROR("Component Init Failed");
Arun Menon906de572013-06-18 17:01:40 -07001947 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001948 DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
Arun Menon906de572013-06-18 17:01:40 -07001949 }
1950 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1951 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001952}
1953
1954/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001955 FUNCTION
1956 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001957
Arun Menon906de572013-06-18 17:01:40 -07001958 DESCRIPTION
1959 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001960
Arun Menon906de572013-06-18 17:01:40 -07001961 PARAMETERS
1962 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001963
Arun Menon906de572013-06-18 17:01:40 -07001964 RETURN VALUE
1965 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001966
Arun Menon906de572013-06-18 17:01:40 -07001967 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001968OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001969(
1970 OMX_IN OMX_HANDLETYPE hComp,
1971 OMX_OUT OMX_STRING componentName,
1972 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1973 OMX_OUT OMX_VERSIONTYPE* specVersion,
1974 OMX_OUT OMX_UUIDTYPE* componentUUID
1975 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001976{
Arun Menon906de572013-06-18 17:01:40 -07001977 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001978 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001979 return OMX_ErrorInvalidState;
1980 }
Arun Menon906de572013-06-18 17:01:40 -07001981 /* TBD -- Return the proper version */
1982 if (specVersion) {
1983 specVersion->nVersion = OMX_SPEC_VERSION;
1984 }
1985 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001986}
1987/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001988 FUNCTION
1989 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001990
Arun Menon906de572013-06-18 17:01:40 -07001991 DESCRIPTION
1992 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001993
Arun Menon906de572013-06-18 17:01:40 -07001994 PARAMETERS
1995 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001996
Arun Menon906de572013-06-18 17:01:40 -07001997 RETURN VALUE
1998 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001999
Arun Menon906de572013-06-18 17:01:40 -07002000 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002001OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002002 OMX_IN OMX_COMMANDTYPE cmd,
2003 OMX_IN OMX_U32 param1,
2004 OMX_IN OMX_PTR cmdData
2005 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002006{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002007 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07002008 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002009 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002010 return OMX_ErrorInvalidState;
2011 }
2012 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07002013 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002014 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07002015 "to invalid port: %lu", param1);
2016 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002017 }
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -07002018
Shalaj Jain273b3e02012-06-22 19:08:03 -07002019 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
2020 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002021 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002022 return OMX_ErrorNone;
2023}
2024
2025/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002026 FUNCTION
2027 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07002028
Arun Menon906de572013-06-18 17:01:40 -07002029 DESCRIPTION
2030 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07002031
Arun Menon906de572013-06-18 17:01:40 -07002032 PARAMETERS
2033 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002034
Arun Menon906de572013-06-18 17:01:40 -07002035 RETURN VALUE
2036 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002037
Arun Menon906de572013-06-18 17:01:40 -07002038 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002039OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002040 OMX_IN OMX_COMMANDTYPE cmd,
2041 OMX_IN OMX_U32 param1,
2042 OMX_IN OMX_PTR cmdData
2043 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002044{
Arun Menon906de572013-06-18 17:01:40 -07002045 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2046 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
2047 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002048
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002049 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
2050 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07002051 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002052
Arun Menon906de572013-06-18 17:01:40 -07002053 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002054 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
2055 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07002056 /***************************/
2057 /* Current State is Loaded */
2058 /***************************/
2059 if (m_state == OMX_StateLoaded) {
2060 if (eState == OMX_StateIdle) {
2061 //if all buffers are allocated or all ports disabled
2062 if (allocate_done() ||
2063 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002064 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002065 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002066 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002067 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
2068 // Skip the event notification
2069 bFlag = 0;
2070 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002071 }
Arun Menon906de572013-06-18 17:01:40 -07002072 /* Requesting transition from Loaded to Loaded */
2073 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002074 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002075 post_event(OMX_EventError,OMX_ErrorSameState,\
2076 OMX_COMPONENT_GENERATE_EVENT);
2077 eRet = OMX_ErrorSameState;
2078 }
2079 /* Requesting transition from Loaded to WaitForResources */
2080 else if (eState == OMX_StateWaitForResources) {
2081 /* Since error is None , we will post an event
2082 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002083 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002084 }
2085 /* Requesting transition from Loaded to Executing */
2086 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002087 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002088 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2089 OMX_COMPONENT_GENERATE_EVENT);
2090 eRet = OMX_ErrorIncorrectStateTransition;
2091 }
2092 /* Requesting transition from Loaded to Pause */
2093 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002094 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002095 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2096 OMX_COMPONENT_GENERATE_EVENT);
2097 eRet = OMX_ErrorIncorrectStateTransition;
2098 }
2099 /* Requesting transition from Loaded to Invalid */
2100 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002101 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002102 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2103 eRet = OMX_ErrorInvalidState;
2104 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002105 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07002106 eState);
2107 eRet = OMX_ErrorBadParameter;
2108 }
2109 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002110
Arun Menon906de572013-06-18 17:01:40 -07002111 /***************************/
2112 /* Current State is IDLE */
2113 /***************************/
2114 else if (m_state == OMX_StateIdle) {
2115 if (eState == OMX_StateLoaded) {
2116 if (release_done()) {
2117 /*
2118 Since error is None , we will post an event at the end
2119 of this function definition
2120 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002121 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002122 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002123 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002124 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2125 // Skip the event notification
2126 bFlag = 0;
2127 }
2128 }
2129 /* Requesting transition from Idle to Executing */
2130 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002131 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002132 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2133 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002134 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002135 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002136 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07002137 }
2138 /* Requesting transition from Idle to Idle */
2139 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002140 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002141 post_event(OMX_EventError,OMX_ErrorSameState,\
2142 OMX_COMPONENT_GENERATE_EVENT);
2143 eRet = OMX_ErrorSameState;
2144 }
2145 /* Requesting transition from Idle to WaitForResources */
2146 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002147 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002148 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2149 OMX_COMPONENT_GENERATE_EVENT);
2150 eRet = OMX_ErrorIncorrectStateTransition;
2151 }
2152 /* Requesting transition from Idle to Pause */
2153 else if (eState == OMX_StatePause) {
2154 /*To pause the Video core we need to start the driver*/
2155 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2156 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002157 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002158 omx_report_error ();
2159 eRet = OMX_ErrorHardware;
2160 } else {
2161 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002162 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002163 bFlag = 0;
2164 }
2165 }
2166 /* Requesting transition from Idle to Invalid */
2167 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002168 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002169 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2170 eRet = OMX_ErrorInvalidState;
2171 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002172 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002173 eRet = OMX_ErrorBadParameter;
2174 }
2175 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002176
Arun Menon906de572013-06-18 17:01:40 -07002177 /******************************/
2178 /* Current State is Executing */
2179 /******************************/
2180 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002181 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002182 /* Requesting transition from Executing to Idle */
2183 if (eState == OMX_StateIdle) {
2184 /* Since error is None , we will post an event
2185 at the end of this function definition
2186 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002187 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002188 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2189 if (!sem_posted) {
2190 sem_posted = 1;
2191 sem_post (&m_cmd_lock);
2192 execute_omx_flush(OMX_ALL);
2193 }
2194 bFlag = 0;
2195 }
2196 /* Requesting transition from Executing to Paused */
2197 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002198 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002199 m_state = OMX_StatePause;
2200 bFlag = 1;
2201 }
2202 /* Requesting transition from Executing to Loaded */
2203 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002204 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002205 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2206 OMX_COMPONENT_GENERATE_EVENT);
2207 eRet = OMX_ErrorIncorrectStateTransition;
2208 }
2209 /* Requesting transition from Executing to WaitForResources */
2210 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002211 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002212 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2213 OMX_COMPONENT_GENERATE_EVENT);
2214 eRet = OMX_ErrorIncorrectStateTransition;
2215 }
2216 /* Requesting transition from Executing to Executing */
2217 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002218 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002219 post_event(OMX_EventError,OMX_ErrorSameState,\
2220 OMX_COMPONENT_GENERATE_EVENT);
2221 eRet = OMX_ErrorSameState;
2222 }
2223 /* Requesting transition from Executing to Invalid */
2224 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002225 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002226 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2227 eRet = OMX_ErrorInvalidState;
2228 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002229 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002230 eRet = OMX_ErrorBadParameter;
2231 }
2232 }
2233 /***************************/
2234 /* Current State is Pause */
2235 /***************************/
2236 else if (m_state == OMX_StatePause) {
2237 /* Requesting transition from Pause to Executing */
2238 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002239 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002240 m_state = OMX_StateExecuting;
2241 bFlag = 1;
2242 }
2243 /* Requesting transition from Pause to Idle */
2244 else if (eState == OMX_StateIdle) {
2245 /* Since error is None , we will post an event
2246 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002247 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002248 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2249 if (!sem_posted) {
2250 sem_posted = 1;
2251 sem_post (&m_cmd_lock);
2252 execute_omx_flush(OMX_ALL);
2253 }
2254 bFlag = 0;
2255 }
2256 /* Requesting transition from Pause to loaded */
2257 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002258 DEBUG_PRINT_ERROR("Pause --> loaded");
Arun Menon906de572013-06-18 17:01:40 -07002259 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2260 OMX_COMPONENT_GENERATE_EVENT);
2261 eRet = OMX_ErrorIncorrectStateTransition;
2262 }
2263 /* Requesting transition from Pause to WaitForResources */
2264 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002265 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002266 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2267 OMX_COMPONENT_GENERATE_EVENT);
2268 eRet = OMX_ErrorIncorrectStateTransition;
2269 }
2270 /* Requesting transition from Pause to Pause */
2271 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002272 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002273 post_event(OMX_EventError,OMX_ErrorSameState,\
2274 OMX_COMPONENT_GENERATE_EVENT);
2275 eRet = OMX_ErrorSameState;
2276 }
2277 /* Requesting transition from Pause to Invalid */
2278 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002279 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002280 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2281 eRet = OMX_ErrorInvalidState;
2282 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002283 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002284 eRet = OMX_ErrorBadParameter;
2285 }
2286 }
2287 /***************************/
2288 /* Current State is WaitForResources */
2289 /***************************/
2290 else if (m_state == OMX_StateWaitForResources) {
2291 /* Requesting transition from WaitForResources to Loaded */
2292 if (eState == OMX_StateLoaded) {
2293 /* Since error is None , we will post an event
2294 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002295 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002296 }
2297 /* Requesting transition from WaitForResources to WaitForResources */
2298 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002299 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002300 post_event(OMX_EventError,OMX_ErrorSameState,
2301 OMX_COMPONENT_GENERATE_EVENT);
2302 eRet = OMX_ErrorSameState;
2303 }
2304 /* Requesting transition from WaitForResources to Executing */
2305 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002306 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002307 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2308 OMX_COMPONENT_GENERATE_EVENT);
2309 eRet = OMX_ErrorIncorrectStateTransition;
2310 }
2311 /* Requesting transition from WaitForResources to Pause */
2312 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002313 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002314 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2315 OMX_COMPONENT_GENERATE_EVENT);
2316 eRet = OMX_ErrorIncorrectStateTransition;
2317 }
2318 /* Requesting transition from WaitForResources to Invalid */
2319 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002320 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002321 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2322 eRet = OMX_ErrorInvalidState;
2323 }
2324 /* Requesting transition from WaitForResources to Loaded -
2325 is NOT tested by Khronos TS */
2326
2327 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002328 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002329 eRet = OMX_ErrorBadParameter;
2330 }
2331 }
2332 /********************************/
2333 /* Current State is Invalid */
2334 /*******************************/
2335 else if (m_state == OMX_StateInvalid) {
2336 /* State Transition from Inavlid to any state */
2337 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2338 || OMX_StateIdle || OMX_StateExecuting
2339 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002340 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002341 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2342 OMX_COMPONENT_GENERATE_EVENT);
2343 eRet = OMX_ErrorInvalidState;
2344 }
2345 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002346 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002347 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002348#ifdef _MSM8974_
2349 send_codec_config();
2350#endif
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302351 if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
2352 param1 == OMX_ALL)) {
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05302353 if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302354 struct timespec ts;
2355
2356 clock_gettime(CLOCK_REALTIME, &ts);
2357 ts.tv_sec += 2;
2358 DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
2359 m_queued_codec_config_count);
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05302360 BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302361 if (sem_timedwait(&m_safe_flush, &ts)) {
2362 DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302363 }
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05302364 BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302365 }
2366 }
2367
Arun Menon906de572013-06-18 17:01:40 -07002368 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2369 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2370 }
2371 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2372 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2373 }
2374 if (!sem_posted) {
2375 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002376 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002377 sem_post (&m_cmd_lock);
2378 execute_omx_flush(param1);
2379 }
2380 bFlag = 0;
2381 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002382 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002383 "with param1: %lu", param1);
2384 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2385 m_inp_bEnabled = OMX_TRUE;
2386
2387 if ( (m_state == OMX_StateLoaded &&
2388 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2389 || allocate_input_done()) {
2390 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2391 OMX_COMPONENT_GENERATE_EVENT);
2392 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002393 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002394 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2395 // Skip the event notification
2396 bFlag = 0;
2397 }
2398 }
2399 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002400 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002401 m_out_bEnabled = OMX_TRUE;
2402
2403 if ( (m_state == OMX_StateLoaded &&
2404 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2405 || (allocate_output_done())) {
2406 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2407 OMX_COMPONENT_GENERATE_EVENT);
2408
2409 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002410 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002411 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2412 // Skip the event notification
2413 bFlag = 0;
2414 }
2415 }
2416 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002417 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002418 "with param1: %lu", param1);
2419 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002420 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002421 m_inp_bEnabled = OMX_FALSE;
2422 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2423 && release_input_done()) {
2424 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2425 OMX_COMPONENT_GENERATE_EVENT);
2426 } else {
2427 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2428 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2429 if (!sem_posted) {
2430 sem_posted = 1;
2431 sem_post (&m_cmd_lock);
2432 }
2433 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2434 }
2435
2436 // Skip the event notification
2437 bFlag = 0;
2438 }
2439 }
2440 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2441 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002442 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002443 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2444 && release_output_done()) {
2445 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2446 OMX_COMPONENT_GENERATE_EVENT);
2447 } else {
2448 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2449 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2450 if (!sem_posted) {
2451 sem_posted = 1;
2452 sem_post (&m_cmd_lock);
2453 }
2454 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2455 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2456 }
2457 // Skip the event notification
2458 bFlag = 0;
2459
2460 }
2461 }
2462 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002463 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002464 eRet = OMX_ErrorNotImplemented;
2465 }
2466 if (eRet == OMX_ErrorNone && bFlag) {
2467 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2468 }
2469 if (!sem_posted) {
2470 sem_post(&m_cmd_lock);
2471 }
2472
2473 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002474}
2475
2476/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002477 FUNCTION
2478 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002479
Arun Menon906de572013-06-18 17:01:40 -07002480 DESCRIPTION
2481 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002482
Arun Menon906de572013-06-18 17:01:40 -07002483 PARAMETERS
2484 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002485
Arun Menon906de572013-06-18 17:01:40 -07002486 RETURN VALUE
2487 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002488
Arun Menon906de572013-06-18 17:01:40 -07002489 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002490bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2491{
Arun Menon906de572013-06-18 17:01:40 -07002492 bool bRet = false;
2493 struct v4l2_plane plane;
2494 struct v4l2_buffer v4l2_buf;
2495 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302496 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002497 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2498 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002499
Arun Menon906de572013-06-18 17:01:40 -07002500 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002501
Arun Menon906de572013-06-18 17:01:40 -07002502 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2503 output_flush_progress = true;
2504 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2505 } else {
2506 /* XXX: The driver/hardware does not support flushing of individual ports
2507 * in all states. So we pretty much need to flush both ports internally,
2508 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2509 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2510 * we automatically omit sending the FLUSH done for the "opposite" port. */
2511 input_flush_progress = true;
2512 output_flush_progress = true;
2513 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2514 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002515
Arun Menon906de572013-06-18 17:01:40 -07002516 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002517 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002518 bRet = false;
2519 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002520
Arun Menon906de572013-06-18 17:01:40 -07002521 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002522}
2523/*=========================================================================
2524FUNCTION : execute_output_flush
2525
2526DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002527Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002528
2529PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002530None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002531
2532RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002533true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002534==========================================================================*/
2535bool omx_vdec::execute_output_flush()
2536{
Arun Menon906de572013-06-18 17:01:40 -07002537 unsigned p1 = 0; // Parameter - 1
2538 unsigned p2 = 0; // Parameter - 2
2539 unsigned ident = 0;
2540 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002541
Arun Menon906de572013-06-18 17:01:40 -07002542 /*Generate FBD for all Buffers in the FTBq*/
2543 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002544 DEBUG_PRINT_LOW("Initiate Output Flush");
vivek mehta79cff222014-01-22 12:17:07 -08002545
2546 //reset last render TS
2547 if(m_last_rendered_TS > 0) {
2548 m_last_rendered_TS = 0;
2549 }
vivek mehtaa75c69f2014-01-10 21:50:37 -08002550
Arun Menon906de572013-06-18 17:01:40 -07002551 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002552 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002553 m_ftb_q.m_size,pending_output_buffers);
2554 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002555 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002556 if (ident == m_fill_output_msg ) {
2557 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2558 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2559 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2560 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002561 }
Arun Menon906de572013-06-18 17:01:40 -07002562 pthread_mutex_unlock(&m_lock);
2563 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002564
Arun Menon906de572013-06-18 17:01:40 -07002565 if (arbitrary_bytes) {
2566 prev_ts = LLONG_MAX;
2567 rst_prev_ts = true;
2568 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002569 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002570 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002571}
2572/*=========================================================================
2573FUNCTION : execute_input_flush
2574
2575DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002576Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002577
2578PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002579None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002580
2581RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002582true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002583==========================================================================*/
2584bool omx_vdec::execute_input_flush()
2585{
Arun Menon906de572013-06-18 17:01:40 -07002586 unsigned i =0;
2587 unsigned p1 = 0; // Parameter - 1
2588 unsigned p2 = 0; // Parameter - 2
2589 unsigned ident = 0;
2590 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002591
Arun Menon906de572013-06-18 17:01:40 -07002592 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002593 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002594
Arun Menon906de572013-06-18 17:01:40 -07002595 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002596 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002597 while (m_etb_q.m_size) {
2598 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002599
Arun Menon906de572013-06-18 17:01:40 -07002600 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002601 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002602 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2603 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2604 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002605 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002606 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2607 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2608 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002609 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002610 (OMX_BUFFERHEADERTYPE *)p1);
2611 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2612 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002613 }
Arun Menon906de572013-06-18 17:01:40 -07002614 time_stamp_dts.flush_timestamp();
2615 /*Check if Heap Buffers are to be flushed*/
2616 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002617 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002618 h264_scratch.nFilledLen = 0;
2619 nal_count = 0;
2620 look_ahead_nal = false;
2621 frame_count = 0;
2622 h264_last_au_ts = LLONG_MAX;
2623 h264_last_au_flags = 0;
2624 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2625 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002626 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002627 if (m_frame_parser.mutils) {
2628 m_frame_parser.mutils->initialize_frame_checking_environment();
2629 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002630
Arun Menon906de572013-06-18 17:01:40 -07002631 while (m_input_pending_q.m_size) {
2632 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2633 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2634 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002635
Arun Menon906de572013-06-18 17:01:40 -07002636 if (psource_frame) {
2637 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2638 psource_frame = NULL;
2639 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002640
Arun Menon906de572013-06-18 17:01:40 -07002641 if (pdest_frame) {
2642 pdest_frame->nFilledLen = 0;
2643 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2644 (unsigned int)NULL);
2645 pdest_frame = NULL;
2646 }
2647 m_frame_parser.flush();
2648 } else if (codec_config_flag) {
2649 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2650 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002651 }
Arun Menon906de572013-06-18 17:01:40 -07002652 pthread_mutex_unlock(&m_lock);
2653 input_flush_progress = false;
2654 if (!arbitrary_bytes) {
2655 prev_ts = LLONG_MAX;
2656 rst_prev_ts = true;
2657 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002658#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002659 if (m_debug_timestamp) {
2660 m_timestamp_list.reset_ts_list();
2661 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002662#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002663 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002664 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002665}
2666
2667
2668/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002669 FUNCTION
2670 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002671
Arun Menon906de572013-06-18 17:01:40 -07002672 DESCRIPTION
2673 Send the event to decoder pipe. This is needed to generate the callbacks
2674 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002675
Arun Menon906de572013-06-18 17:01:40 -07002676 PARAMETERS
2677 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002678
Arun Menon906de572013-06-18 17:01:40 -07002679 RETURN VALUE
2680 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002681
Arun Menon906de572013-06-18 17:01:40 -07002682 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002683bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002684 unsigned int p2,
2685 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002686{
Arun Menon906de572013-06-18 17:01:40 -07002687 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002688
2689
Arun Menon906de572013-06-18 17:01:40 -07002690 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002691
Arun Menon906de572013-06-18 17:01:40 -07002692 if (id == m_fill_output_msg ||
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05302693 id == OMX_COMPONENT_GENERATE_FBD ||
2694 id == OMX_COMPONENT_GENERATE_PORT_RECONFIG) {
Arun Menon906de572013-06-18 17:01:40 -07002695 m_ftb_q.insert_entry(p1,p2,id);
2696 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2697 id == OMX_COMPONENT_GENERATE_EBD ||
2698 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2699 m_etb_q.insert_entry(p1,p2,id);
2700 } else {
2701 m_cmd_q.insert_entry(p1,p2,id);
2702 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002703
Arun Menon906de572013-06-18 17:01:40 -07002704 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002705 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002706 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002707
Arun Menon906de572013-06-18 17:01:40 -07002708 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002709
Arun Menon906de572013-06-18 17:01:40 -07002710 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002711}
2712
2713OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2714{
Arun Menon906de572013-06-18 17:01:40 -07002715 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2716 if (!profileLevelType)
2717 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002718
Arun Menon906de572013-06-18 17:01:40 -07002719 if (profileLevelType->nPortIndex == 0) {
2720 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2721 if (profileLevelType->nProfileIndex == 0) {
2722 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2723 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002724
Arun Menon906de572013-06-18 17:01:40 -07002725 } else if (profileLevelType->nProfileIndex == 1) {
2726 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2727 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2728 } else if (profileLevelType->nProfileIndex == 2) {
2729 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2730 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2731 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002732 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002733 profileLevelType->nProfileIndex);
2734 eRet = OMX_ErrorNoMore;
2735 }
2736 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2737 if (profileLevelType->nProfileIndex == 0) {
2738 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2739 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2740 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002741 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002742 eRet = OMX_ErrorNoMore;
2743 }
2744 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2745 if (profileLevelType->nProfileIndex == 0) {
2746 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2747 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2748 } else if (profileLevelType->nProfileIndex == 1) {
2749 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2750 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2751 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002752 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002753 eRet = OMX_ErrorNoMore;
2754 }
2755 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2756 eRet = OMX_ErrorNoMore;
2757 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2758 if (profileLevelType->nProfileIndex == 0) {
2759 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2760 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2761 } else if (profileLevelType->nProfileIndex == 1) {
2762 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2763 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2764 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002765 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002766 eRet = OMX_ErrorNoMore;
2767 }
2768 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002769 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002770 eRet = OMX_ErrorNoMore;
2771 }
2772 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002773 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002774 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002775 }
Arun Menon906de572013-06-18 17:01:40 -07002776 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002777}
2778
2779/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002780 FUNCTION
2781 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002782
Arun Menon906de572013-06-18 17:01:40 -07002783 DESCRIPTION
2784 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002785
Arun Menon906de572013-06-18 17:01:40 -07002786 PARAMETERS
2787 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002788
Arun Menon906de572013-06-18 17:01:40 -07002789 RETURN VALUE
2790 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002791
Arun Menon906de572013-06-18 17:01:40 -07002792 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002793OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002794 OMX_IN OMX_INDEXTYPE paramIndex,
2795 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002796{
2797 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2798
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002799 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002800 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002801 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002802 return OMX_ErrorInvalidState;
2803 }
Arun Menon906de572013-06-18 17:01:40 -07002804 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002805 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002806 return OMX_ErrorBadParameter;
2807 }
Arun Menon906de572013-06-18 17:01:40 -07002808 switch ((unsigned long)paramIndex) {
2809 case OMX_IndexParamPortDefinition: {
2810 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2811 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002812 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002813 eRet = update_portdef(portDefn);
2814 if (eRet == OMX_ErrorNone)
2815 m_port_def = *portDefn;
2816 break;
2817 }
2818 case OMX_IndexParamVideoInit: {
2819 OMX_PORT_PARAM_TYPE *portParamType =
2820 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002821 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002822
Arun Menon906de572013-06-18 17:01:40 -07002823 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2824 portParamType->nSize = sizeof(portParamType);
2825 portParamType->nPorts = 2;
2826 portParamType->nStartPortNumber = 0;
2827 break;
2828 }
2829 case OMX_IndexParamVideoPortFormat: {
2830 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2831 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002832 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002833
Arun Menon906de572013-06-18 17:01:40 -07002834 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2835 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002836
Arun Menon906de572013-06-18 17:01:40 -07002837 if (0 == portFmt->nPortIndex) {
2838 if (0 == portFmt->nIndex) {
2839 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2840 portFmt->eCompressionFormat = eCompressionFormat;
2841 } else {
2842 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002843 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002844 eRet = OMX_ErrorNoMore;
2845 }
2846 } else if (1 == portFmt->nPortIndex) {
2847 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002848
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07002849 // Distinguish non-surface mode from normal playback use-case based on
2850 // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
2851 // For non-android, use the default list
Praveen Chavancac86402014-10-18 09:14:52 -07002852 // Also use default format-list if FLEXIBLE YUV is supported,
2853 // as the client negotiates the standard color-format if it needs to
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07002854 bool useNonSurfaceMode = false;
Praveen Chavancac86402014-10-18 09:14:52 -07002855#if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED)
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07002856 useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
2857#endif
2858 portFmt->eColorFormat = useNonSurfaceMode ?
2859 getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
2860 getPreferredColorFormatDefaultMode(portFmt->nIndex);
2861
2862 if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
Praveen Chavandb7776f2014-02-06 18:17:25 -08002863 eRet = OMX_ErrorNoMore;
Arun Menon906de572013-06-18 17:01:40 -07002864 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002865 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002866 }
Praveen Chavandb7776f2014-02-06 18:17:25 -08002867 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002868 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002869 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002870 (int)portFmt->nPortIndex);
2871 eRet = OMX_ErrorBadPortIndex;
2872 }
2873 break;
2874 }
2875 /*Component should support this port definition*/
2876 case OMX_IndexParamAudioInit: {
2877 OMX_PORT_PARAM_TYPE *audioPortParamType =
2878 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002879 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002880 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2881 audioPortParamType->nSize = sizeof(audioPortParamType);
2882 audioPortParamType->nPorts = 0;
2883 audioPortParamType->nStartPortNumber = 0;
2884 break;
2885 }
2886 /*Component should support this port definition*/
2887 case OMX_IndexParamImageInit: {
2888 OMX_PORT_PARAM_TYPE *imagePortParamType =
2889 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002890 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002891 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2892 imagePortParamType->nSize = sizeof(imagePortParamType);
2893 imagePortParamType->nPorts = 0;
2894 imagePortParamType->nStartPortNumber = 0;
2895 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002896
Arun Menon906de572013-06-18 17:01:40 -07002897 }
2898 /*Component should support this port definition*/
2899 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002900 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002901 paramIndex);
2902 eRet =OMX_ErrorUnsupportedIndex;
2903 break;
2904 }
2905 case OMX_IndexParamStandardComponentRole: {
2906 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2907 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2908 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2909 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002910
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002911 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002912 paramIndex);
2913 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2914 OMX_MAX_STRINGNAME_SIZE);
2915 break;
2916 }
2917 /* Added for parameter test */
2918 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002919
Arun Menon906de572013-06-18 17:01:40 -07002920 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2921 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002922 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002923 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2924 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002925
Arun Menon906de572013-06-18 17:01:40 -07002926 break;
2927 }
2928 /* Added for parameter test */
2929 case OMX_IndexParamCompBufferSupplier: {
2930 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2931 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002932 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002933
Arun Menon906de572013-06-18 17:01:40 -07002934 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2935 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2936 if (0 == bufferSupplierType->nPortIndex)
2937 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2938 else if (1 == bufferSupplierType->nPortIndex)
2939 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2940 else
2941 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002942
2943
Arun Menon906de572013-06-18 17:01:40 -07002944 break;
2945 }
2946 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002947 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002948 paramIndex);
2949 break;
2950 }
2951 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002952 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002953 paramIndex);
2954 break;
2955 }
2956 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002957 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002958 paramIndex);
2959 break;
2960 }
2961 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002962 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002963 paramIndex);
2964 break;
2965 }
2966 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002967 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002968 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2969 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2970 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2971 break;
2972 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002973#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002974 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002975 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002976 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2977 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002978
Arun Menon906de572013-06-18 17:01:40 -07002979 if (secure_mode) {
2980 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2981 GRALLOC_USAGE_PRIVATE_UNCACHED);
2982 } else {
2983 nativeBuffersUsage->nUsage =
2984 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2985 GRALLOC_USAGE_PRIVATE_UNCACHED);
2986 }
2987 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002988 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002989 eRet = OMX_ErrorBadParameter;
2990 }
2991 }
2992 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002993#endif
2994
Praveen Chavan09a82b72014-10-18 09:09:45 -07002995#ifdef FLEXYUV_SUPPORTED
2996 case OMX_QcomIndexFlexibleYUVDescription: {
2997 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
2998 eRet = describeColorFormat(paramData);
2999 break;
3000 }
3001#endif
3002
Arun Menon906de572013-06-18 17:01:40 -07003003 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003004 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003005 eRet =OMX_ErrorUnsupportedIndex;
3006 }
3007
Shalaj Jain273b3e02012-06-22 19:08:03 -07003008 }
3009
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003010 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07003011 drv_ctx.video_resolution.frame_width,
3012 drv_ctx.video_resolution.frame_height,
3013 drv_ctx.video_resolution.stride,
3014 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003015
Arun Menon906de572013-06-18 17:01:40 -07003016 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003017}
3018
3019#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3020OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
3021{
3022 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
3023 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3024 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
3025
Arun Menon906de572013-06-18 17:01:40 -07003026 if ((params == NULL) ||
3027 (params->nativeBuffer == NULL) ||
3028 (params->nativeBuffer->handle == NULL) ||
3029 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003030 return OMX_ErrorBadParameter;
3031 m_use_android_native_buffers = OMX_TRUE;
3032 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3033 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07003034 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 -07003035 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07003036 if (!secure_mode) {
3037 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003038 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07003039 if (buffer == MAP_FAILED) {
3040 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3041 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003042 }
3043 }
3044 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3045 } else {
3046 eRet = OMX_ErrorBadParameter;
3047 }
3048 return eRet;
3049}
3050#endif
Praveen Chavancf924182013-12-06 23:16:23 -08003051
3052OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
3053 struct v4l2_control control;
3054 struct v4l2_format fmt;
3055 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3056 control.value = 1;
3057 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3058 if (rc < 0) {
3059 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3060 return OMX_ErrorHardware;
3061 }
3062 m_smoothstreaming_mode = true;
3063 return OMX_ErrorNone;
3064}
3065
Shalaj Jain273b3e02012-06-22 19:08:03 -07003066/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003067 FUNCTION
3068 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07003069
Arun Menon906de572013-06-18 17:01:40 -07003070 DESCRIPTION
3071 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003072
Arun Menon906de572013-06-18 17:01:40 -07003073 PARAMETERS
3074 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003075
Arun Menon906de572013-06-18 17:01:40 -07003076 RETURN VALUE
3077 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003078
Arun Menon906de572013-06-18 17:01:40 -07003079 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003080OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003081 OMX_IN OMX_INDEXTYPE paramIndex,
3082 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003083{
3084 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003085 int ret=0;
3086 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07003087 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003088 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003089 return OMX_ErrorInvalidState;
3090 }
Arun Menon906de572013-06-18 17:01:40 -07003091 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003092 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07003093 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003094 }
Arun Menon906de572013-06-18 17:01:40 -07003095 if ((m_state != OMX_StateLoaded) &&
3096 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3097 (m_out_bEnabled == OMX_TRUE) &&
3098 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3099 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003100 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003101 return OMX_ErrorIncorrectStateOperation;
3102 }
Arun Menon906de572013-06-18 17:01:40 -07003103 switch ((unsigned long)paramIndex) {
3104 case OMX_IndexParamPortDefinition: {
3105 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3106 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3107 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3108 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003109 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07003110 (int)portDefn->format.video.nFrameHeight,
3111 (int)portDefn->format.video.nFrameWidth);
3112 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003113 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Pushkaraj Patil41588352014-02-25 20:51:34 +05303114 bool port_format_changed = false;
Arun Menon906de572013-06-18 17:01:40 -07003115 m_display_id = portDefn->format.video.pNativeWindow;
3116 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08003117 /* update output port resolution with client supplied dimensions
3118 in case scaling is enabled, else it follows input resolution set
3119 */
3120 if (is_down_scalar_enabled) {
3121 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003122 portDefn->format.video.nFrameWidth,
3123 portDefn->format.video.nFrameHeight);
3124 if (portDefn->format.video.nFrameHeight != 0x0 &&
3125 portDefn->format.video.nFrameWidth != 0x0) {
Pushkaraj Patil41588352014-02-25 20:51:34 +05303126 memset(&fmt, 0x0, sizeof(struct v4l2_format));
3127 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3128 fmt.fmt.pix_mp.pixelformat = capture_capability;
3129 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
3130 if (ret) {
3131 DEBUG_PRINT_ERROR("Get Resolution failed");
3132 eRet = OMX_ErrorHardware;
3133 break;
3134 }
3135 if ((portDefn->format.video.nFrameHeight != (int)fmt.fmt.pix_mp.height) ||
3136 (portDefn->format.video.nFrameWidth != (int)fmt.fmt.pix_mp.width)) {
3137 port_format_changed = true;
3138 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003139 update_resolution(portDefn->format.video.nFrameWidth,
3140 portDefn->format.video.nFrameHeight,
3141 portDefn->format.video.nFrameWidth,
3142 portDefn->format.video.nFrameHeight);
Pushkaraj Patil41588352014-02-25 20:51:34 +05303143
3144 /* set crop info */
3145 rectangle.nLeft = 0;
3146 rectangle.nTop = 0;
3147 rectangle.nWidth = portDefn->format.video.nFrameWidth;
3148 rectangle.nHeight = portDefn->format.video.nFrameHeight;
3149
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003150 eRet = is_video_session_supported();
3151 if (eRet)
3152 break;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303153 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003154 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3155 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3156 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3157 fmt.fmt.pix_mp.pixelformat = capture_capability;
3158 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);
3159 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3160 if (ret) {
3161 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3162 eRet = OMX_ErrorUnsupportedSetting;
3163 } else
3164 eRet = get_buffer_req(&drv_ctx.op_buf);
3165 }
Praveen Chavane78460c2013-12-06 23:16:04 -08003166 }
Arun Menon906de572013-06-18 17:01:40 -07003167 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003168 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07003169 eRet = OMX_ErrorBadParameter;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303170 } else if (!port_format_changed) {
Arun Menon906de572013-06-18 17:01:40 -07003171 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3172 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
3173 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3174 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3175 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
3176 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
3177 drv_ctx.extradata_info.buffer_size;
3178 eRet = set_buffer_req(&drv_ctx.op_buf);
3179 if (eRet == OMX_ErrorNone)
3180 m_port_def = *portDefn;
3181 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003182 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003183 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3184 portDefn->nBufferCountActual, portDefn->nBufferSize);
3185 eRet = OMX_ErrorBadParameter;
3186 }
3187 }
3188 } else if (OMX_DirInput == portDefn->eDir) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003189 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003190 bool port_format_changed = false;
3191 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
3192 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
3193 // Frame rate only should be set if this is a "known value" or to
3194 // activate ts prediction logic (arbitrary mode only) sending input
3195 // timestamps with max value (LLONG_MAX).
3196 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
3197 portDefn->format.video.xFramerate >> 16);
3198 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3199 drv_ctx.frame_rate.fps_denominator);
3200 if (!drv_ctx.frame_rate.fps_numerator) {
3201 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3202 drv_ctx.frame_rate.fps_numerator = 30;
3203 }
3204 if (drv_ctx.frame_rate.fps_denominator)
3205 drv_ctx.frame_rate.fps_numerator = (int)
3206 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3207 drv_ctx.frame_rate.fps_denominator = 1;
3208 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3209 drv_ctx.frame_rate.fps_numerator;
3210 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3211 frm_int, drv_ctx.frame_rate.fps_numerator /
3212 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003213
3214 struct v4l2_outputparm oparm;
3215 /*XXX: we're providing timing info as seconds per frame rather than frames
3216 * per second.*/
3217 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3218 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3219
3220 struct v4l2_streamparm sparm;
3221 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3222 sparm.parm.output = oparm;
3223 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3224 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
3225 eRet = OMX_ErrorHardware;
3226 break;
3227 }
Arun Menon906de572013-06-18 17:01:40 -07003228 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003229
Arun Menon906de572013-06-18 17:01:40 -07003230 if (drv_ctx.video_resolution.frame_height !=
3231 portDefn->format.video.nFrameHeight ||
3232 drv_ctx.video_resolution.frame_width !=
3233 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003234 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003235 portDefn->format.video.nFrameWidth,
3236 portDefn->format.video.nFrameHeight);
3237 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003238 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3239 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3240 if (frameHeight != 0x0 && frameWidth != 0x0) {
3241 if (m_smoothstreaming_mode &&
3242 ((frameWidth * frameHeight) <
3243 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3244 frameWidth = m_smoothstreaming_width;
3245 frameHeight = m_smoothstreaming_height;
3246 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3247 frameWidth, frameHeight);
3248 }
3249 update_resolution(frameWidth, frameHeight,
3250 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003251 eRet = is_video_session_supported();
3252 if (eRet)
3253 break;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303254 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Arun Menon906de572013-06-18 17:01:40 -07003255 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3256 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3257 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3258 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003259 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 -07003260 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3261 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003262 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003263 eRet = OMX_ErrorUnsupportedSetting;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303264 } else {
3265 if (!is_down_scalar_enabled)
3266 eRet = get_buffer_req(&drv_ctx.op_buf);
3267 }
Arun Menon906de572013-06-18 17:01:40 -07003268 }
3269 }
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +05303270 if (m_custom_buffersize.input_buffersize
3271 && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
3272 DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
3273 m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
3274 eRet = OMX_ErrorBadParameter;
3275 break;
3276 }
Arun Menon906de572013-06-18 17:01:40 -07003277 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3278 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3279 port_format_changed = true;
3280 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3281 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3282 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3283 (~(buffer_prop->alignment - 1));
3284 eRet = set_buffer_req(buffer_prop);
3285 }
3286 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003287 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003288 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3289 portDefn->nBufferCountActual, portDefn->nBufferSize);
3290 eRet = OMX_ErrorBadParameter;
3291 }
3292 } else if (portDefn->eDir == OMX_DirMax) {
3293 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3294 (int)portDefn->nPortIndex);
3295 eRet = OMX_ErrorBadPortIndex;
3296 }
3297 }
3298 break;
3299 case OMX_IndexParamVideoPortFormat: {
3300 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3301 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3302 int ret=0;
3303 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003304 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003305 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003306
Arun Menon906de572013-06-18 17:01:40 -07003307 if (1 == portFmt->nPortIndex) {
3308 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3309 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3310 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3311 fmt.fmt.pix_mp.pixelformat = capture_capability;
3312 enum vdec_output_fromat op_format;
3313 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3314 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Praveen Chavandb7776f2014-02-06 18:17:25 -08003315 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
3316 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar))
Arun Menon906de572013-06-18 17:01:40 -07003317 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Arun Menon906de572013-06-18 17:01:40 -07003318 else
3319 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003320
Arun Menon906de572013-06-18 17:01:40 -07003321 if (eRet == OMX_ErrorNone) {
3322 drv_ctx.output_format = op_format;
3323 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3324 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003325 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003326 eRet = OMX_ErrorUnsupportedSetting;
3327 /*TODO: How to handle this case */
3328 } else {
3329 eRet = get_buffer_req(&drv_ctx.op_buf);
3330 }
3331 }
3332 if (eRet == OMX_ErrorNone) {
3333 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003334 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003335 eRet = OMX_ErrorBadParameter;
3336 }
3337 }
3338 }
3339 }
3340 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003341
Arun Menon906de572013-06-18 17:01:40 -07003342 case OMX_QcomIndexPortDefn: {
3343 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3344 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003345 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003346 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003347
Arun Menon906de572013-06-18 17:01:40 -07003348 /* Input port */
3349 if (portFmt->nPortIndex == 0) {
3350 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3351 if (secure_mode) {
3352 arbitrary_bytes = false;
3353 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3354 eRet = OMX_ErrorUnsupportedSetting;
3355 } else {
3356 arbitrary_bytes = true;
3357 }
3358 } else if (portFmt->nFramePackingFormat ==
3359 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3360 arbitrary_bytes = false;
3361 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003362 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003363 portFmt->nFramePackingFormat);
3364 eRet = OMX_ErrorUnsupportedSetting;
3365 }
3366 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003367 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003368 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3369 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3370 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3371 m_out_mem_region_smi = OMX_TRUE;
3372 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003373 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003374 m_use_output_pmem = OMX_TRUE;
3375 }
3376 }
3377 }
3378 }
3379 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003380
Arun Menon906de572013-06-18 17:01:40 -07003381 case OMX_IndexParamStandardComponentRole: {
3382 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3383 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003384 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003385 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003386
Arun Menon906de572013-06-18 17:01:40 -07003387 if ((m_state == OMX_StateLoaded)&&
3388 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3389 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3390 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003391 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003392 return OMX_ErrorIncorrectStateOperation;
3393 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003394
Arun Menon906de572013-06-18 17:01:40 -07003395 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3396 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3397 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3398 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003399 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003400 eRet =OMX_ErrorUnsupportedSetting;
3401 }
3402 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3403 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3404 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3405 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003406 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003407 eRet = OMX_ErrorUnsupportedSetting;
3408 }
3409 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3410 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3411 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3412 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003413 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003414 eRet =OMX_ErrorUnsupportedSetting;
3415 }
3416 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3417 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3418 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3419 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003420 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003421 eRet = OMX_ErrorUnsupportedSetting;
3422 }
3423 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
Deva Ramasubramanianba4534b2013-12-17 15:52:37 -08003424 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) ||
3425 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE))
Arun Menon906de572013-06-18 17:01:40 -07003426 ) {
3427 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3428 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3429 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003430 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003431 eRet =OMX_ErrorUnsupportedSetting;
3432 }
3433 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3434 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3435 ) {
3436 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3437 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3438 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003439 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003440 eRet =OMX_ErrorUnsupportedSetting;
3441 }
3442 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3443 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3444 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3445 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3446 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003447 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003448 eRet = OMX_ErrorUnsupportedSetting;
3449 }
3450 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003451 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003452 eRet = OMX_ErrorInvalidComponentName;
3453 }
3454 break;
3455 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003456
Arun Menon906de572013-06-18 17:01:40 -07003457 case OMX_IndexParamPriorityMgmt: {
3458 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003459 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003460 return OMX_ErrorIncorrectStateOperation;
3461 }
3462 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003463 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003464 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003465
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003466 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003467 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003468
Arun Menon906de572013-06-18 17:01:40 -07003469 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3470 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003471
Arun Menon906de572013-06-18 17:01:40 -07003472 break;
3473 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003474
Arun Menon906de572013-06-18 17:01:40 -07003475 case OMX_IndexParamCompBufferSupplier: {
3476 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003477 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003478 bufferSupplierType->eBufferSupplier);
3479 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3480 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003481
Arun Menon906de572013-06-18 17:01:40 -07003482 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003483
Arun Menon906de572013-06-18 17:01:40 -07003484 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003485
Arun Menon906de572013-06-18 17:01:40 -07003486 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003487
Arun Menon906de572013-06-18 17:01:40 -07003488 }
3489 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003490 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003491 paramIndex);
3492 break;
3493 }
3494 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003495 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003496 paramIndex);
3497 break;
3498 }
3499 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003500 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003501 paramIndex);
3502 break;
3503 }
3504 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003505 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003506 paramIndex);
3507 break;
3508 }
3509 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3510 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3511 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3512 struct v4l2_control control;
3513 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003514 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003515 pictureOrder->eOutputPictureOrder);
3516 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3517 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3518 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3519 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3520 time_stamp_dts.set_timestamp_reorder_mode(false);
3521 } else
3522 eRet = OMX_ErrorBadParameter;
3523 if (eRet == OMX_ErrorNone) {
3524 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3525 control.value = pic_order;
3526 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3527 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003528 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003529 eRet = OMX_ErrorUnsupportedSetting;
3530 }
3531 }
3532 break;
3533 }
3534 case OMX_QcomIndexParamConcealMBMapExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303535 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3536 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3537 break;
3538 case OMX_QcomIndexParamFrameInfoExtraData:
3539 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3540 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3541 break;
Arun Menon906de572013-06-18 17:01:40 -07003542 case OMX_QcomIndexParamInterlaceExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303543 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3544 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3545 break;
Arun Menon906de572013-06-18 17:01:40 -07003546 case OMX_QcomIndexParamH264TimeInfo:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303547 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3548 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3549 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303550 case OMX_QcomIndexParamVideoFramePackingExtradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303551 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3552 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3553 break;
3554 case OMX_QcomIndexParamVideoQPExtraData:
3555 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
3556 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3557 break;
3558 case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
3559 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
3560 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3561 break;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05303562 case OMX_QcomIndexEnableExtnUserData:
3563 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
3564 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3565 break;
Arun Menon906de572013-06-18 17:01:40 -07003566 case OMX_QcomIndexParamVideoDivx: {
3567 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3568 }
3569 break;
3570 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003571 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003572 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3573 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3574 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3575 eRet = OMX_ErrorUnsupportedSetting;
3576 } else {
3577 m_out_pvt_entry_pmem = OMX_TRUE;
3578 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003579 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003580 m_use_output_pmem = OMX_TRUE;
3581 }
3582 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003583
Arun Menon906de572013-06-18 17:01:40 -07003584 }
3585 break;
3586 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3587 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3588 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3589 struct v4l2_control control;
3590 int rc;
3591 drv_ctx.idr_only_decoding = 1;
3592 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3593 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3594 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3595 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003596 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003597 eRet = OMX_ErrorUnsupportedSetting;
3598 } else {
3599 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3600 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3601 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3602 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003603 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003604 eRet = OMX_ErrorUnsupportedSetting;
3605 }
3606 /*Setting sync frame decoding on driver might change buffer
3607 * requirements so update them here*/
3608 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003609 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003610 eRet = OMX_ErrorUnsupportedSetting;
3611 }
3612 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003613 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003614 eRet = OMX_ErrorUnsupportedSetting;
3615 }
3616 }
3617 }
3618 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003619
Arun Menon906de572013-06-18 17:01:40 -07003620 case OMX_QcomIndexParamIndexExtraDataType: {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303621 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3622 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3623 (extradataIndexType->bEnabled == OMX_TRUE) &&
3624 (extradataIndexType->nPortIndex == 1)) {
3625 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
3626 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
3627 }
3628 }
Arun Menon906de572013-06-18 17:01:40 -07003629 break;
3630 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003631#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003632 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003633#else
Arun Menon906de572013-06-18 17:01:40 -07003634 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003635#endif
Arun Menon906de572013-06-18 17:01:40 -07003636 }
3637 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003638#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003639 /* Need to allow following two set_parameters even in Idle
3640 * state. This is ANDROID architecture which is not in sync
3641 * with openmax standard. */
3642 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3643 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3644 if (enableNativeBuffers) {
3645 m_enable_android_native_buffers = enableNativeBuffers->enable;
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07003646 }
Praveen Chavancac86402014-10-18 09:14:52 -07003647#if !defined(FLEXYUV_SUPPORTED)
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07003648 if (m_enable_android_native_buffers) {
3649 // Use the most-preferred-native-color-format as surface-mode is hinted here
3650 if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
3651 DEBUG_PRINT_ERROR("Failed to set native color format!");
3652 eRet = OMX_ErrorUnsupportedSetting;
3653 }
Arun Menon906de572013-06-18 17:01:40 -07003654 }
Praveen Chavancac86402014-10-18 09:14:52 -07003655#endif
Arun Menon906de572013-06-18 17:01:40 -07003656 }
3657 break;
3658 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3659 eRet = use_android_native_buffer(hComp, paramData);
3660 }
3661 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003662#endif
Arun Menon906de572013-06-18 17:01:40 -07003663 case OMX_QcomIndexParamEnableTimeStampReorder: {
3664 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3665 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3666 if (reorder->bEnable == OMX_TRUE) {
3667 frm_int =0;
3668 time_stamp_dts.set_timestamp_reorder_mode(true);
3669 } else
3670 time_stamp_dts.set_timestamp_reorder_mode(false);
3671 } else {
3672 time_stamp_dts.set_timestamp_reorder_mode(false);
3673 if (reorder->bEnable == OMX_TRUE) {
3674 eRet = OMX_ErrorUnsupportedSetting;
3675 }
3676 }
3677 }
3678 break;
3679 case OMX_IndexParamVideoProfileLevelCurrent: {
3680 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3681 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3682 if (pParam) {
3683 m_profile_lvl.eProfile = pParam->eProfile;
3684 m_profile_lvl.eLevel = pParam->eLevel;
3685 }
3686 break;
Arun Menon888aa852013-05-30 11:24:42 -07003687
Arun Menon906de572013-06-18 17:01:40 -07003688 }
Arun Menone5652482013-08-04 13:33:05 -07003689 case OMX_QcomIndexParamVideoMetaBufferMode:
3690 {
3691 StoreMetaDataInBuffersParams *metabuffer =
3692 (StoreMetaDataInBuffersParams *)paramData;
3693 if (!metabuffer) {
3694 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3695 eRet = OMX_ErrorBadParameter;
3696 break;
3697 }
3698 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3699 //set property dynamic buffer mode to driver.
3700 struct v4l2_control control;
3701 struct v4l2_format fmt;
3702 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3703 if (metabuffer->bStoreMetaData == true) {
3704 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3705 } else {
3706 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3707 }
3708 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3709 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003710 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003711 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003712 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003713 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003714 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003715 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3716 eRet = OMX_ErrorUnsupportedSetting;
3717 }
3718 } else {
3719 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003720 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003721 metabuffer->nPortIndex);
3722 eRet = OMX_ErrorUnsupportedSetting;
3723 }
3724 break;
3725 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003726 case OMX_QcomIndexParamVideoDownScalar: {
3727 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3728 struct v4l2_control control;
3729 int rc;
3730 if (pParam) {
3731 is_down_scalar_enabled = pParam->bEnable;
3732 if (is_down_scalar_enabled) {
3733 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3734 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3735 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3736 pParam->bEnable);
3737 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3738 if (rc < 0) {
3739 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3740 eRet = OMX_ErrorUnsupportedSetting;
3741 }
3742 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3743 control.value = 1;
3744 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3745 if (rc < 0) {
3746 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3747 eRet = OMX_ErrorUnsupportedSetting;
3748 }
3749 }
3750 }
3751 break;
3752 }
Praveen Chavancf924182013-12-06 23:16:23 -08003753#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3754 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3755 {
3756 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3757 PrepareForAdaptivePlaybackParams* pParams =
3758 (PrepareForAdaptivePlaybackParams *) paramData;
3759 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3760 if (!pParams->bEnable) {
3761 return OMX_ErrorNone;
3762 }
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303763 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
3764 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
Praveen Chavancf924182013-12-06 23:16:23 -08003765 DEBUG_PRINT_ERROR(
3766 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3767 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303768 maxSmoothStreamingWidth, maxSmoothStreamingHeight);
Praveen Chavancf924182013-12-06 23:16:23 -08003769 eRet = OMX_ErrorBadParameter;
3770 } else {
Arun Menon1fc764f2014-04-17 15:41:27 -07003771 eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3772 }
Praveen Chavancf924182013-12-06 23:16:23 -08003773 } else {
3774 DEBUG_PRINT_ERROR(
3775 "Prepare for adaptive playback supported only on output port");
3776 eRet = OMX_ErrorBadParameter;
3777 }
3778 break;
3779 }
3780
3781#endif
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +05303782 case OMX_QcomIndexParamVideoCustomBufferSize:
3783 {
3784 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
3785 QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
3786 if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3787 struct v4l2_control control;
3788 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
3789 control.value = pParam->nBufferSize;
3790 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
3791 DEBUG_PRINT_ERROR("Failed to set input buffer size");
3792 eRet = OMX_ErrorUnsupportedSetting;
3793 } else {
3794 eRet = get_buffer_req(&drv_ctx.ip_buf);
3795 if (eRet == OMX_ErrorNone) {
3796 m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
3797 DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
3798 m_custom_buffersize.input_buffersize);
3799 } else {
3800 DEBUG_PRINT_ERROR("Failed to get buffer requirement");
3801 }
3802 }
3803 } else {
3804 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
3805 eRet = OMX_ErrorBadParameter;
3806 }
3807 break;
3808 }
Arun Menon906de572013-06-18 17:01:40 -07003809 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003810 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003811 eRet = OMX_ErrorUnsupportedIndex;
3812 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003813 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003814 if (eRet != OMX_ErrorNone)
3815 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003816 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003817}
3818
3819/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003820 FUNCTION
3821 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003822
Arun Menon906de572013-06-18 17:01:40 -07003823 DESCRIPTION
3824 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003825
Arun Menon906de572013-06-18 17:01:40 -07003826 PARAMETERS
3827 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003828
Arun Menon906de572013-06-18 17:01:40 -07003829 RETURN VALUE
3830 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003831
Arun Menon906de572013-06-18 17:01:40 -07003832 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003833OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003834 OMX_IN OMX_INDEXTYPE configIndex,
3835 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003836{
Arun Menon906de572013-06-18 17:01:40 -07003837 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003838
Arun Menon906de572013-06-18 17:01:40 -07003839 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003840 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003841 return OMX_ErrorInvalidState;
3842 }
Arun Menon906de572013-06-18 17:01:40 -07003843
3844 switch ((unsigned long)configIndex) {
3845 case OMX_QcomIndexConfigInterlaced: {
3846 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3847 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3848 if (configFmt->nPortIndex == 1) {
3849 if (configFmt->nIndex == 0) {
3850 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3851 } else if (configFmt->nIndex == 1) {
3852 configFmt->eInterlaceType =
3853 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3854 } else if (configFmt->nIndex == 2) {
3855 configFmt->eInterlaceType =
3856 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3857 } else {
3858 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003859 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003860 eRet = OMX_ErrorNoMore;
3861 }
3862
3863 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003864 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003865 (int)configFmt->nPortIndex);
3866 eRet = OMX_ErrorBadPortIndex;
3867 }
3868 break;
3869 }
3870 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3871 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3872 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3873 decoderinstances->nNumOfInstances = 16;
3874 /*TODO: How to handle this case */
3875 break;
3876 }
3877 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3878 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3879 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3880 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303881 memcpy(configFmt, &m_frame_pack_arrangement,
3882 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003883 } else {
3884 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3885 }
3886 break;
3887 }
3888 case OMX_IndexConfigCommonOutputCrop: {
3889 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3890 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05303891 DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
3892 rectangle.nLeft, rectangle.nTop,
3893 rectangle.nWidth, rectangle.nHeight);
Arun Menon906de572013-06-18 17:01:40 -07003894 break;
3895 }
3896 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003897 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003898 eRet = OMX_ErrorBadParameter;
3899 }
3900
Shalaj Jain273b3e02012-06-22 19:08:03 -07003901 }
Arun Menon906de572013-06-18 17:01:40 -07003902
3903 return eRet;
3904}
3905
3906/* ======================================================================
3907 FUNCTION
3908 omx_vdec::SetConfig
3909
3910 DESCRIPTION
3911 OMX Set Config method implementation
3912
3913 PARAMETERS
3914 <TBD>.
3915
3916 RETURN VALUE
3917 OMX Error None if successful.
3918 ========================================================================== */
3919OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3920 OMX_IN OMX_INDEXTYPE configIndex,
3921 OMX_IN OMX_PTR configData)
3922{
3923 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003924 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003925 return OMX_ErrorInvalidState;
3926 }
3927
3928 OMX_ERRORTYPE ret = OMX_ErrorNone;
3929 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3930
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003931 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003932
3933 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3934 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003935 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003936 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003937 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003938 OMX_U32 extra_size;
3939 // Parsing done here for the AVC atom is definitely not generic
3940 // Currently this piece of code is working, but certainly
3941 // not tested with all .mp4 files.
3942 // Incase of failure, we might need to revisit this
3943 // for a generic piece of code.
3944
3945 // Retrieve size of NAL length field
3946 // byte #4 contains the size of NAL lenght field
3947 nal_length = (config->pData[4] & 0x03) + 1;
3948
3949 extra_size = 0;
3950 if (nal_length > 2) {
3951 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3952 extra_size = (nal_length - 2) * 2;
3953 }
3954
3955 // SPS starts from byte #6
3956 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3957 OMX_U8 *pDestBuf;
3958 m_vendor_config.nPortIndex = config->nPortIndex;
3959
3960 // minus 6 --> SPS starts from byte #6
3961 // minus 1 --> picture param set byte to be ignored from avcatom
3962 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3963 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3964 OMX_U32 len;
3965 OMX_U8 index = 0;
3966 // case where SPS+PPS is sent as part of set_config
3967 pDestBuf = m_vendor_config.pData;
3968
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003969 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003970 m_vendor_config.nPortIndex,
3971 m_vendor_config.nDataSize,
3972 m_vendor_config.pData);
3973 while (index < 2) {
3974 uint8 *psize;
3975 len = *pSrcBuf;
3976 len = len << 8;
3977 len |= *(pSrcBuf + 1);
3978 psize = (uint8 *) & len;
3979 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3980 for (unsigned int i = 0; i < nal_length; i++) {
3981 pDestBuf[i] = psize[nal_length - 1 - i];
3982 }
3983 //memcpy(pDestBuf,pSrcBuf,(len+2));
3984 pDestBuf += len + nal_length;
3985 pSrcBuf += len + 2;
3986 index++;
3987 pSrcBuf++; // skip picture param set
3988 len = 0;
3989 }
3990 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3991 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3992 m_vendor_config.nPortIndex = config->nPortIndex;
3993 m_vendor_config.nDataSize = config->nDataSize;
3994 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3995 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3996 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3997 if (m_vendor_config.pData) {
3998 free(m_vendor_config.pData);
3999 m_vendor_config.pData = NULL;
4000 m_vendor_config.nDataSize = 0;
4001 }
4002
4003 if (((*((OMX_U32 *) config->pData)) &
4004 VC1_SP_MP_START_CODE_MASK) ==
4005 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004006 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07004007 m_vendor_config.nPortIndex = config->nPortIndex;
4008 m_vendor_config.nDataSize = config->nDataSize;
4009 m_vendor_config.pData =
4010 (OMX_U8 *) malloc(config->nDataSize);
4011 memcpy(m_vendor_config.pData, config->pData,
4012 config->nDataSize);
4013 m_vc1_profile = VC1_SP_MP_RCV;
4014 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004015 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07004016 m_vendor_config.nPortIndex = config->nPortIndex;
4017 m_vendor_config.nDataSize = config->nDataSize;
4018 m_vendor_config.pData =
4019 (OMX_U8 *) malloc((config->nDataSize));
4020 memcpy(m_vendor_config.pData, config->pData,
4021 config->nDataSize);
4022 m_vc1_profile = VC1_AP;
4023 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004024 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07004025 m_vendor_config.nPortIndex = config->nPortIndex;
4026 m_vendor_config.nDataSize = config->nDataSize;
4027 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
4028 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
4029 m_vc1_profile = VC1_SP_MP_RCV;
4030 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004031 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07004032 }
4033 }
4034 return ret;
4035 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
4036 struct v4l2_control temp;
4037 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
4038
4039 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
4040 switch (pNal->nNaluBytes) {
4041 case 0:
4042 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
4043 break;
4044 case 2:
4045 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
4046 break;
4047 case 4:
4048 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
4049 break;
4050 default:
4051 return OMX_ErrorUnsupportedSetting;
4052 }
4053
4054 if (!arbitrary_bytes) {
4055 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
4056 * with start code, so only need to notify driver in frame by frame mode */
4057 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
4058 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
4059 return OMX_ErrorHardware;
4060 }
4061 }
4062
4063 nal_length = pNal->nNaluBytes;
4064 m_frame_parser.init_nal_length(nal_length);
4065
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004066 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07004067 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05304068 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07004069 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05304070 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07004071
4072 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
4073 if (config->bEnabled) {
4074 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05304075 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07004076 config->nFps >> 16);
4077 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
4078 drv_ctx.frame_rate.fps_denominator);
4079
4080 if (!drv_ctx.frame_rate.fps_numerator) {
4081 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
4082 drv_ctx.frame_rate.fps_numerator = 30;
4083 }
4084
4085 if (drv_ctx.frame_rate.fps_denominator) {
4086 drv_ctx.frame_rate.fps_numerator = (int)
4087 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
4088 }
4089
4090 drv_ctx.frame_rate.fps_denominator = 1;
4091 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
4092 drv_ctx.frame_rate.fps_numerator;
4093
4094 struct v4l2_outputparm oparm;
4095 /*XXX: we're providing timing info as seconds per frame rather than frames
4096 * per second.*/
4097 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
4098 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
4099
4100 struct v4l2_streamparm sparm;
4101 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4102 sparm.parm.output = oparm;
4103 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
4104 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
4105 performance might be affected");
4106 ret = OMX_ErrorHardware;
4107 }
4108 client_set_fps = true;
4109 } else {
4110 DEBUG_PRINT_ERROR("Frame rate not supported.");
4111 ret = OMX_ErrorUnsupportedSetting;
4112 }
4113 } else {
4114 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
4115 client_set_fps = false;
4116 }
4117 } else {
4118 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
4119 (int)config->nPortIndex);
4120 ret = OMX_ErrorBadPortIndex;
4121 }
4122
4123 return ret;
4124 }
4125
4126 return OMX_ErrorNotImplemented;
4127}
4128
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304129#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
4130
Arun Menon906de572013-06-18 17:01:40 -07004131/* ======================================================================
4132 FUNCTION
4133 omx_vdec::GetExtensionIndex
4134
4135 DESCRIPTION
4136 OMX GetExtensionIndex method implementaion. <TBD>
4137
4138 PARAMETERS
4139 <TBD>.
4140
4141 RETURN VALUE
4142 OMX Error None if everything successful.
4143
4144 ========================================================================== */
4145OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
4146 OMX_IN OMX_STRING paramName,
4147 OMX_OUT OMX_INDEXTYPE* indexType)
4148{
4149 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004150 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004151 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304152 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07004153 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304154 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004155 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304156 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
4157 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
4158 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
4159 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08004160 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
4161 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08004162 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
4163 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08004164 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
4165 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004166 }
4167#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304168 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004169 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304170 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004171 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304172 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004173 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004174 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304175 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004176 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4177 }
4178#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304179 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07004180 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
4181 }
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05304182#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Praveen Chavancf924182013-12-06 23:16:23 -08004183 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
4184 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
4185 }
4186#endif
Praveen Chavan09a82b72014-10-18 09:09:45 -07004187#ifdef FLEXYUV_SUPPORTED
4188 else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
4189 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
4190 }
4191#endif
Arun Menon906de572013-06-18 17:01:40 -07004192 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004193 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004194 return OMX_ErrorNotImplemented;
4195 }
4196 return OMX_ErrorNone;
4197}
4198
4199/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004200 FUNCTION
4201 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07004202
Arun Menon906de572013-06-18 17:01:40 -07004203 DESCRIPTION
4204 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004205
Arun Menon906de572013-06-18 17:01:40 -07004206 PARAMETERS
4207 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004208
Arun Menon906de572013-06-18 17:01:40 -07004209 RETURN VALUE
4210 Error None if everything is successful.
4211 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004212OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004213 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004214{
Arun Menon906de572013-06-18 17:01:40 -07004215 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004216 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07004217 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004218}
4219
4220/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004221 FUNCTION
4222 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07004223
Arun Menon906de572013-06-18 17:01:40 -07004224 DESCRIPTION
4225 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004226
Arun Menon906de572013-06-18 17:01:40 -07004227 PARAMETERS
4228 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004229
Arun Menon906de572013-06-18 17:01:40 -07004230 RETURN VALUE
4231 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004232
Arun Menon906de572013-06-18 17:01:40 -07004233 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004234OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004235 OMX_IN OMX_U32 port,
4236 OMX_IN OMX_HANDLETYPE peerComponent,
4237 OMX_IN OMX_U32 peerPort,
4238 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004239{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004240 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07004241 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004242}
4243
4244/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004245 FUNCTION
4246 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004247
Arun Menon906de572013-06-18 17:01:40 -07004248 DESCRIPTION
4249 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004250
Arun Menon906de572013-06-18 17:01:40 -07004251 PARAMETERS
4252 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004253
Arun Menon906de572013-06-18 17:01:40 -07004254 RETURN VALUE
4255 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004256
Arun Menon906de572013-06-18 17:01:40 -07004257 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004258OMX_ERRORTYPE omx_vdec::allocate_extradata()
4259{
4260#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004261 if (drv_ctx.extradata_info.buffer_size) {
4262 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4263 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4264 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4265 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004266 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004267 }
4268 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4269 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4270 drv_ctx.extradata_info.size, 4096,
4271 &drv_ctx.extradata_info.ion.ion_alloc_data,
4272 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4273 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004274 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004275 return OMX_ErrorInsufficientResources;
4276 }
4277 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4278 drv_ctx.extradata_info.size,
4279 PROT_READ|PROT_WRITE, MAP_SHARED,
4280 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4281 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004282 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004283 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4284 free_ion_memory(&drv_ctx.extradata_info.ion);
4285 return OMX_ErrorInsufficientResources;
4286 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004287 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004288#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304289 if (!m_other_extradata) {
4290 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4291 if (!m_other_extradata) {
4292 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4293 return OMX_ErrorInsufficientResources;
4294 }
4295 }
Arun Menon906de572013-06-18 17:01:40 -07004296 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004297}
4298
Arun Menon906de572013-06-18 17:01:40 -07004299void omx_vdec::free_extradata()
4300{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004301#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004302 if (drv_ctx.extradata_info.uaddr) {
4303 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4304 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4305 free_ion_memory(&drv_ctx.extradata_info.ion);
4306 }
4307 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004308#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304309 if (m_other_extradata) {
4310 free(m_other_extradata);
4311 m_other_extradata = NULL;
4312 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004313}
4314
Shalaj Jain273b3e02012-06-22 19:08:03 -07004315OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004316 OMX_IN OMX_HANDLETYPE hComp,
4317 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4318 OMX_IN OMX_U32 port,
4319 OMX_IN OMX_PTR appData,
4320 OMX_IN OMX_U32 bytes,
4321 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004322{
Arun Menon906de572013-06-18 17:01:40 -07004323 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4324 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4325 unsigned i= 0; // Temporary counter
4326 struct vdec_setbuffer_cmd setbuffers;
4327 OMX_PTR privateAppData = NULL;
4328 private_handle_t *handle = NULL;
4329 OMX_U8 *buff = buffer;
4330 struct v4l2_buffer buf;
4331 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4332 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004333
Arun Menon906de572013-06-18 17:01:40 -07004334 if (!m_out_mem_ptr) {
4335 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4336 eRet = allocate_output_headers();
4337 if (eRet == OMX_ErrorNone)
4338 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004339 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004340
Arun Menon906de572013-06-18 17:01:40 -07004341 if (eRet == OMX_ErrorNone) {
4342 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4343 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4344 break;
4345 }
4346 }
4347 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004348
Arun Menon906de572013-06-18 17:01:40 -07004349 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004350 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004351 eRet = OMX_ErrorInsufficientResources;
4352 }
4353
Arun Menonbdb80b02013-08-12 17:45:54 -07004354 if (dynamic_buf_mode) {
4355 *bufferHdr = (m_out_mem_ptr + i );
4356 (*bufferHdr)->pBuffer = NULL;
4357 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4358 enum v4l2_buf_type buf_type;
4359 int rr = 0;
4360 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4361 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4362 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4363 return OMX_ErrorInsufficientResources;
4364 } else {
4365 streaming[CAPTURE_PORT] = true;
4366 DEBUG_PRINT_LOW("STREAMON Successful");
4367 }
4368 }
4369 BITMASK_SET(&m_out_bm_count,i);
4370 (*bufferHdr)->pAppPrivate = appData;
4371 (*bufferHdr)->pBuffer = buffer;
4372 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4373 return eRet;
4374 }
Arun Menon906de572013-06-18 17:01:40 -07004375 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004376#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004377 if (m_enable_android_native_buffers) {
4378 if (m_use_android_native_buffers) {
4379 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4380 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4381 handle = (private_handle_t *)nBuf->handle;
4382 privateAppData = params->pAppPrivate;
4383 } else {
4384 handle = (private_handle_t *)buff;
4385 privateAppData = appData;
4386 }
Arun Menon8544ead2014-05-08 17:42:29 -07004387 if (!handle) {
4388 DEBUG_PRINT_ERROR("handle is invalid");
4389 return OMX_ErrorBadParameter;
4390 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004391
Arun Menon906de572013-06-18 17:01:40 -07004392 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4393 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4394 " expected %u, got %lu",
4395 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4396 return OMX_ErrorBadParameter;
4397 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004398
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07004399 drv_ctx.op_buf.buffer_size = handle->size;
4400
Arun Menon906de572013-06-18 17:01:40 -07004401 if (!m_use_android_native_buffers) {
4402 if (!secure_mode) {
4403 buff = (OMX_U8*)mmap(0, handle->size,
4404 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4405 if (buff == MAP_FAILED) {
4406 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4407 return OMX_ErrorInsufficientResources;
4408 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004409 }
4410 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004411#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004412 native_buffer[i].nativehandle = handle;
4413 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004414#endif
Arun Menon906de572013-06-18 17:01:40 -07004415 if (!handle) {
4416 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4417 return OMX_ErrorBadParameter;
4418 }
4419 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4420 drv_ctx.ptr_outputbuffer[i].offset = 0;
4421 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4422 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4423 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4424 } else
4425#endif
4426
4427 if (!ouput_egl_buffers && !m_use_output_pmem) {
4428#ifdef USE_ION
4429 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4430 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4431 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4432 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4433 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004434 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 -07004435 return OMX_ErrorInsufficientResources;
4436 }
4437 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4438 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4439#else
4440 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4441 open (MEM_DEVICE,O_RDWR);
4442
4443 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004444 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004445 return OMX_ErrorInsufficientResources;
4446 }
4447
4448 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4449 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4450 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4451 open (MEM_DEVICE,O_RDWR);
4452 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004453 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004454 return OMX_ErrorInsufficientResources;
4455 }
4456 }
4457
4458 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4459 drv_ctx.op_buf.buffer_size,
4460 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004461 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004462 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4463 return OMX_ErrorInsufficientResources;
4464 }
4465#endif
4466 if (!secure_mode) {
4467 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4468 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4469 PROT_READ|PROT_WRITE, MAP_SHARED,
4470 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4471 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4472 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4473#ifdef USE_ION
4474 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4475#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004476 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004477 return OMX_ErrorInsufficientResources;
4478 }
4479 }
4480 drv_ctx.ptr_outputbuffer[i].offset = 0;
4481 privateAppData = appData;
4482 } else {
4483
4484 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4485 if (!appData || !bytes ) {
4486 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004487 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004488 return OMX_ErrorBadParameter;
4489 }
4490 }
4491
4492 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4493 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4494 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
Arun Menon8544ead2014-05-08 17:42:29 -07004495 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
Arun Menon906de572013-06-18 17:01:40 -07004496 !pmem_list->nEntries ||
4497 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004498 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004499 return OMX_ErrorBadParameter;
4500 }
4501 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4502 pmem_list->entryList->entry;
4503 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4504 pmem_info->pmem_fd);
4505 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4506 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4507 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4508 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4509 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4510 privateAppData = appData;
4511 }
4512 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4513 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304514 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4515 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4516 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004517
4518 *bufferHdr = (m_out_mem_ptr + i );
4519 if (secure_mode)
4520 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4521 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4522 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4523 sizeof (vdec_bufferpayload));
4524
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004525 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004526 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4527 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4528
4529 buf.index = i;
4530 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4531 buf.memory = V4L2_MEMORY_USERPTR;
4532 plane[0].length = drv_ctx.op_buf.buffer_size;
4533 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4534 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4535 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4536 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4537 plane[0].data_offset = 0;
4538 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4539 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4540 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4541 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4542#ifdef USE_ION
4543 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4544#endif
4545 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4546 plane[extra_idx].data_offset = 0;
4547 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004548 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004549 return OMX_ErrorBadParameter;
4550 }
Arun Menon906de572013-06-18 17:01:40 -07004551 buf.m.planes = plane;
4552 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004553
Arun Menon906de572013-06-18 17:01:40 -07004554 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004555 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004556 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004557 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004558 }
4559
Arun Menon906de572013-06-18 17:01:40 -07004560 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4561 enum v4l2_buf_type buf_type;
4562 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4563 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4564 return OMX_ErrorInsufficientResources;
4565 } else {
4566 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004567 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004568 }
4569 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004570
Arun Menon906de572013-06-18 17:01:40 -07004571 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4572 if (m_enable_android_native_buffers) {
4573 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4574 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4575 } else {
4576 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004577 }
Arun Menon906de572013-06-18 17:01:40 -07004578 (*bufferHdr)->pAppPrivate = privateAppData;
4579 BITMASK_SET(&m_out_bm_count,i);
4580 }
4581 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004582}
4583
4584/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004585 FUNCTION
4586 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004587
Arun Menon906de572013-06-18 17:01:40 -07004588 DESCRIPTION
4589 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004590
Arun Menon906de572013-06-18 17:01:40 -07004591 PARAMETERS
4592 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004593
Arun Menon906de572013-06-18 17:01:40 -07004594 RETURN VALUE
4595 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004596
Arun Menon906de572013-06-18 17:01:40 -07004597 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004598OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004599 OMX_IN OMX_HANDLETYPE hComp,
4600 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4601 OMX_IN OMX_U32 port,
4602 OMX_IN OMX_PTR appData,
4603 OMX_IN OMX_U32 bytes,
4604 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004605{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004606 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004607 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4608 if (!m_inp_heap_ptr)
4609 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4610 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4611 drv_ctx.ip_buf.actualcount);
4612 if (!m_phdr_pmem_ptr)
4613 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4614 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4615 drv_ctx.ip_buf.actualcount);
4616 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4617 DEBUG_PRINT_ERROR("Insufficent memory");
4618 eRet = OMX_ErrorInsufficientResources;
4619 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4620 input_use_buffer = true;
4621 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4622 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4623 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4624 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4625 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4626 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4627 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4628 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004629 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 -07004630 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4631 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004632 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004633 return OMX_ErrorInsufficientResources;
4634 }
4635 m_in_alloc_cnt++;
4636 } else {
4637 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4638 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004639 }
Arun Menon906de572013-06-18 17:01:40 -07004640 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004641}
4642
4643/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004644 FUNCTION
4645 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004646
Arun Menon906de572013-06-18 17:01:40 -07004647 DESCRIPTION
4648 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004649
Arun Menon906de572013-06-18 17:01:40 -07004650 PARAMETERS
4651 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004652
Arun Menon906de572013-06-18 17:01:40 -07004653 RETURN VALUE
4654 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004655
Arun Menon906de572013-06-18 17:01:40 -07004656 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004657OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004658 OMX_IN OMX_HANDLETYPE hComp,
4659 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4660 OMX_IN OMX_U32 port,
4661 OMX_IN OMX_PTR appData,
4662 OMX_IN OMX_U32 bytes,
4663 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004664{
Arun Menon906de572013-06-18 17:01:40 -07004665 OMX_ERRORTYPE error = OMX_ErrorNone;
4666 struct vdec_setbuffer_cmd setbuffers;
4667
Arun Menon8544ead2014-05-08 17:42:29 -07004668 if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
4669 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4670 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004671 }
Arun Menon906de572013-06-18 17:01:40 -07004672 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004673 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004674 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004675 }
Arun Menon906de572013-06-18 17:01:40 -07004676 if (port == OMX_CORE_INPUT_PORT_INDEX)
4677 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4678 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4679 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4680 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004681 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004682 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004683 }
Arun Menon906de572013-06-18 17:01:40 -07004684 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4685 if (error == OMX_ErrorNone) {
4686 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4687 // Send the callback now
4688 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4689 post_event(OMX_CommandStateSet,OMX_StateIdle,
4690 OMX_COMPONENT_GENERATE_EVENT);
4691 }
4692 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4693 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4694 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4695 post_event(OMX_CommandPortEnable,
4696 OMX_CORE_INPUT_PORT_INDEX,
4697 OMX_COMPONENT_GENERATE_EVENT);
4698 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4699 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4700 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4701 post_event(OMX_CommandPortEnable,
4702 OMX_CORE_OUTPUT_PORT_INDEX,
4703 OMX_COMPONENT_GENERATE_EVENT);
4704 }
4705 }
4706 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004707}
4708
4709OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004710 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004711{
Arun Menon906de572013-06-18 17:01:40 -07004712 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4713 if (m_inp_heap_ptr[bufferindex].pBuffer)
4714 free(m_inp_heap_ptr[bufferindex].pBuffer);
4715 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4716 }
4717 if (pmem_bufferHdr)
4718 free_input_buffer(pmem_bufferHdr);
4719 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004720}
4721
4722OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4723{
Arun Menon906de572013-06-18 17:01:40 -07004724 unsigned int index = 0;
4725 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4726 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004727 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004728
Arun Menon906de572013-06-18 17:01:40 -07004729 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004730 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004731
4732 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004733 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004734 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4735 struct vdec_setbuffer_cmd setbuffers;
4736 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4737 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4738 sizeof (vdec_bufferpayload));
4739 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004740 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004741 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004742 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004743 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4744 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4745 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4746 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4747 }
4748 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4749 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4750 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4751 free(m_desc_buffer_ptr[index].buf_addr);
4752 m_desc_buffer_ptr[index].buf_addr = NULL;
4753 m_desc_buffer_ptr[index].desc_data_size = 0;
4754 }
4755#ifdef USE_ION
4756 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4757#endif
4758 }
4759 }
4760
4761 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004762}
4763
4764OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4765{
Arun Menon906de572013-06-18 17:01:40 -07004766 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004767
Arun Menon906de572013-06-18 17:01:40 -07004768 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4769 return OMX_ErrorBadParameter;
4770 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004771
Arun Menon906de572013-06-18 17:01:40 -07004772 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004773 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004774
Arun Menon906de572013-06-18 17:01:40 -07004775 if (index < drv_ctx.op_buf.actualcount
4776 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004777 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004778 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004779
Arun Menon906de572013-06-18 17:01:40 -07004780 struct vdec_setbuffer_cmd setbuffers;
4781 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4782 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4783 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004784
4785 if (!dynamic_buf_mode) {
Balamurugan Alagarsamye773c582014-12-17 15:10:25 +05304786 if (streaming[CAPTURE_PORT] &&
4787 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) {
4788 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
4789 DEBUG_PRINT_ERROR("STREAMOFF Failed");
4790 } else {
4791 DEBUG_PRINT_LOW("STREAMOFF Successful");
4792 }
4793 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004794#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004795 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004796 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004797 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4798 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4799 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4800 }
Arun Menon906de572013-06-18 17:01:40 -07004801 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004802 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4803 } else {
4804#endif
4805 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4806 if (!secure_mode) {
4807 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4808 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4809 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4810 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4811 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4812 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4813 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4814 }
4815 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4816 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004817#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004818 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004819#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004820 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004821#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004822 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004823#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004824 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004825 if (release_output_done()) {
4826 free_extradata();
4827 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004828 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004829
Arun Menon906de572013-06-18 17:01:40 -07004830 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004831
4832}
4833
4834OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004835 OMX_BUFFERHEADERTYPE **bufferHdr,
4836 OMX_U32 port,
4837 OMX_PTR appData,
4838 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004839{
Arun Menon906de572013-06-18 17:01:40 -07004840 OMX_BUFFERHEADERTYPE *input = NULL;
4841 unsigned char *buf_addr = NULL;
4842 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4843 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004844
Arun Menon906de572013-06-18 17:01:40 -07004845 /* Sanity Check*/
4846 if (bufferHdr == NULL) {
4847 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004848 }
4849
Arun Menon906de572013-06-18 17:01:40 -07004850 if (m_inp_heap_ptr == NULL) {
4851 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4852 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4853 drv_ctx.ip_buf.actualcount);
4854 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4855 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4856 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004857
Arun Menon8544ead2014-05-08 17:42:29 -07004858 if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
4859 DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004860 return OMX_ErrorInsufficientResources;
4861 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004862 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004863
Arun Menon906de572013-06-18 17:01:40 -07004864 /*Find a Free index*/
4865 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4866 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004867 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004868 break;
4869 }
4870 }
4871
4872 if (i < drv_ctx.ip_buf.actualcount) {
4873 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4874
4875 if (buf_addr == NULL) {
4876 return OMX_ErrorInsufficientResources;
4877 }
4878
4879 *bufferHdr = (m_inp_heap_ptr + i);
4880 input = *bufferHdr;
4881 BITMASK_SET(&m_heap_inp_bm_count,i);
4882
4883 input->pBuffer = (OMX_U8 *)buf_addr;
4884 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4885 input->nVersion.nVersion = OMX_SPEC_VERSION;
4886 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4887 input->pAppPrivate = appData;
4888 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004889 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004890 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004891 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004892 /*Add the Buffers to freeq*/
4893 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4894 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004895 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004896 return OMX_ErrorInsufficientResources;
4897 }
4898 } else {
4899 return OMX_ErrorBadParameter;
4900 }
4901
4902 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004903
4904}
4905
4906
4907/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004908 FUNCTION
4909 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004910
Arun Menon906de572013-06-18 17:01:40 -07004911 DESCRIPTION
4912 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004913
Arun Menon906de572013-06-18 17:01:40 -07004914 PARAMETERS
4915 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004916
Arun Menon906de572013-06-18 17:01:40 -07004917 RETURN VALUE
4918 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004919
Arun Menon906de572013-06-18 17:01:40 -07004920 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004921OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004922 OMX_IN OMX_HANDLETYPE hComp,
4923 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4924 OMX_IN OMX_U32 port,
4925 OMX_IN OMX_PTR appData,
4926 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004927{
4928
Arun Menon906de572013-06-18 17:01:40 -07004929 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4930 struct vdec_setbuffer_cmd setbuffers;
4931 OMX_BUFFERHEADERTYPE *input = NULL;
4932 unsigned i = 0;
4933 unsigned char *buf_addr = NULL;
4934 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004935
Arun Menon906de572013-06-18 17:01:40 -07004936 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004937 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004938 bytes, drv_ctx.ip_buf.buffer_size);
4939 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004940 }
4941
Arun Menon906de572013-06-18 17:01:40 -07004942 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004943 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004944 drv_ctx.ip_buf.actualcount,
4945 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004946
Arun Menon906de572013-06-18 17:01:40 -07004947 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4948 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4949
4950 if (m_inp_mem_ptr == NULL) {
4951 return OMX_ErrorInsufficientResources;
4952 }
4953
4954 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4955 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4956
4957 if (drv_ctx.ptr_inputbuffer == NULL) {
4958 return OMX_ErrorInsufficientResources;
4959 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004960#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004961 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4962 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004963
Arun Menon906de572013-06-18 17:01:40 -07004964 if (drv_ctx.ip_buf_ion_info == NULL) {
4965 return OMX_ErrorInsufficientResources;
4966 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004967#endif
4968
Arun Menon906de572013-06-18 17:01:40 -07004969 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4970 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004971#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004972 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004973#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004974 }
4975 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004976
Arun Menon906de572013-06-18 17:01:40 -07004977 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4978 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004979 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004980 break;
4981 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004982 }
Arun Menon906de572013-06-18 17:01:40 -07004983
4984 if (i < drv_ctx.ip_buf.actualcount) {
4985 struct v4l2_buffer buf;
4986 struct v4l2_plane plane;
4987 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004988 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004989#ifdef USE_ION
4990 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4991 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4992 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4993 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4994 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4995 return OMX_ErrorInsufficientResources;
4996 }
4997 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4998#else
4999 pmem_fd = open (MEM_DEVICE,O_RDWR);
5000
5001 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005002 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005003 return OMX_ErrorInsufficientResources;
5004 }
5005
5006 if (pmem_fd == 0) {
5007 pmem_fd = open (MEM_DEVICE,O_RDWR);
5008
5009 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005010 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005011 return OMX_ErrorInsufficientResources;
5012 }
5013 }
5014
5015 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
5016 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005017 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005018 close(pmem_fd);
5019 return OMX_ErrorInsufficientResources;
5020 }
5021#endif
5022 if (!secure_mode) {
5023 buf_addr = (unsigned char *)mmap(NULL,
5024 drv_ctx.ip_buf.buffer_size,
5025 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
5026
5027 if (buf_addr == MAP_FAILED) {
5028 close(pmem_fd);
5029#ifdef USE_ION
5030 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
5031#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005032 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005033 return OMX_ErrorInsufficientResources;
5034 }
5035 }
5036 *bufferHdr = (m_inp_mem_ptr + i);
5037 if (secure_mode)
5038 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
5039 else
5040 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
5041 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
5042 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
5043 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
5044 drv_ctx.ptr_inputbuffer [i].offset = 0;
5045
5046
5047 buf.index = i;
5048 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5049 buf.memory = V4L2_MEMORY_USERPTR;
5050 plane.bytesused = 0;
5051 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
5052 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
5053 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
5054 plane.reserved[1] = 0;
5055 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
5056 buf.m.planes = &plane;
5057 buf.length = 1;
5058
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005059 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07005060 drv_ctx.ptr_inputbuffer[i].bufferaddr);
5061
5062 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5063
5064 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005065 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07005066 /*TODO: How to handle this case */
5067 return OMX_ErrorInsufficientResources;
5068 }
5069
5070 input = *bufferHdr;
5071 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005072 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07005073 if (secure_mode)
5074 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
5075 else
5076 input->pBuffer = (OMX_U8 *)buf_addr;
5077 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5078 input->nVersion.nVersion = OMX_SPEC_VERSION;
5079 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
5080 input->pAppPrivate = appData;
5081 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
5082 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
5083
5084 if (drv_ctx.disable_dmx) {
5085 eRet = allocate_desc_buffer(i);
5086 }
5087 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005088 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07005089 eRet = OMX_ErrorInsufficientResources;
5090 }
5091 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005092}
5093
5094
5095/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005096 FUNCTION
5097 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005098
Arun Menon906de572013-06-18 17:01:40 -07005099 DESCRIPTION
5100 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07005101
Arun Menon906de572013-06-18 17:01:40 -07005102 PARAMETERS
5103 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005104
Arun Menon906de572013-06-18 17:01:40 -07005105 RETURN VALUE
5106 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005107
Arun Menon906de572013-06-18 17:01:40 -07005108 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005109OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07005110 OMX_IN OMX_HANDLETYPE hComp,
5111 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5112 OMX_IN OMX_U32 port,
5113 OMX_IN OMX_PTR appData,
5114 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005115{
Arun Menon906de572013-06-18 17:01:40 -07005116 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5117 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
5118 unsigned i= 0; // Temporary counter
5119 struct vdec_setbuffer_cmd setbuffers;
5120 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005121#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005122 int ion_device_fd =-1;
5123 struct ion_allocation_data ion_alloc_data;
5124 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005125#endif
Arun Menon906de572013-06-18 17:01:40 -07005126 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005127 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07005128 drv_ctx.op_buf.actualcount,
5129 drv_ctx.op_buf.buffer_size);
5130 int nBufHdrSize = 0;
5131 int nPlatformEntrySize = 0;
5132 int nPlatformListSize = 0;
5133 int nPMEMInfoSize = 0;
5134 int pmem_fd = -1;
5135 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005136
Arun Menon906de572013-06-18 17:01:40 -07005137 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
5138 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
5139 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005140
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005141 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07005142 drv_ctx.op_buf.actualcount);
5143 nBufHdrSize = drv_ctx.op_buf.actualcount *
5144 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005145
Arun Menon906de572013-06-18 17:01:40 -07005146 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
5147 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
5148 nPlatformListSize = drv_ctx.op_buf.actualcount *
5149 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
5150 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
5151 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005152
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005153 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07005154 sizeof(OMX_BUFFERHEADERTYPE),
5155 nPMEMInfoSize,
5156 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005157 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07005158 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005159#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005160 ion_device_fd = alloc_map_ion_memory(
5161 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
5162 drv_ctx.op_buf.alignment,
5163 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
5164 if (ion_device_fd < 0) {
5165 return OMX_ErrorInsufficientResources;
5166 }
5167 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005168#else
Arun Menon906de572013-06-18 17:01:40 -07005169 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005170
Arun Menon906de572013-06-18 17:01:40 -07005171 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005172 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005173 drv_ctx.op_buf.buffer_size);
5174 return OMX_ErrorInsufficientResources;
5175 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005176
Arun Menon906de572013-06-18 17:01:40 -07005177 if (pmem_fd == 0) {
5178 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005179
Arun Menon906de572013-06-18 17:01:40 -07005180 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005181 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005182 drv_ctx.op_buf.buffer_size);
5183 return OMX_ErrorInsufficientResources;
5184 }
5185 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005186
Arun Menon906de572013-06-18 17:01:40 -07005187 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5188 drv_ctx.op_buf.actualcount,
5189 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005190 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005191 close(pmem_fd);
5192 return OMX_ErrorInsufficientResources;
5193 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005194#endif
Arun Menon906de572013-06-18 17:01:40 -07005195 if (!secure_mode) {
5196 pmem_baseaddress = (unsigned char *)mmap(NULL,
5197 (drv_ctx.op_buf.buffer_size *
5198 drv_ctx.op_buf.actualcount),
5199 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5200 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005201 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07005202 drv_ctx.op_buf.buffer_size);
5203 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005204#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005205 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005206#endif
Arun Menon906de572013-06-18 17:01:40 -07005207 return OMX_ErrorInsufficientResources;
5208 }
5209 }
5210 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5211 // Alloc mem for platform specific info
5212 char *pPtr=NULL;
5213 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5214 nPMEMInfoSize,1);
5215 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5216 calloc (sizeof(struct vdec_bufferpayload),
5217 drv_ctx.op_buf.actualcount);
5218 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5219 calloc (sizeof (struct vdec_output_frameinfo),
5220 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005221 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
5222 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
5223 return OMX_ErrorInsufficientResources;
5224 }
5225
Arun Menon906de572013-06-18 17:01:40 -07005226#ifdef USE_ION
5227 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5228 calloc (sizeof(struct vdec_ion),
5229 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005230 if (!drv_ctx.op_buf_ion_info) {
5231 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
5232 return OMX_ErrorInsufficientResources;
5233 }
Arun Menon906de572013-06-18 17:01:40 -07005234#endif
5235
5236 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5237 && drv_ctx.ptr_respbuffer) {
5238 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5239 (drv_ctx.op_buf.buffer_size *
5240 drv_ctx.op_buf.actualcount);
5241 bufHdr = m_out_mem_ptr;
5242 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5243 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5244 (((char *) m_platform_list) + nPlatformListSize);
5245 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5246 (((char *) m_platform_entry) + nPlatformEntrySize);
5247 pPlatformList = m_platform_list;
5248 pPlatformEntry = m_platform_entry;
5249 pPMEMInfo = m_pmem_info;
5250
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005251 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07005252
5253 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005254 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
5255 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07005256 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
5257 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5258 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5259 // Set the values when we determine the right HxW param
5260 bufHdr->nAllocLen = bytes;
5261 bufHdr->nFilledLen = 0;
5262 bufHdr->pAppPrivate = appData;
5263 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5264 // Platform specific PMEM Information
5265 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005266 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005267 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5268 pPlatformEntry->entry = pPMEMInfo;
5269 // Initialize the Platform List
5270 pPlatformList->nEntries = 1;
5271 pPlatformList->entryList = pPlatformEntry;
5272 // Keep pBuffer NULL till vdec is opened
5273 bufHdr->pBuffer = NULL;
5274 bufHdr->nOffset = 0;
5275
5276 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5277 pPMEMInfo->pmem_fd = 0;
5278 bufHdr->pPlatformPrivate = pPlatformList;
5279
5280 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5281 m_pmem_info[i].pmem_fd = pmem_fd;
5282#ifdef USE_ION
5283 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5284 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5285 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5286#endif
5287
5288 /*Create a mapping between buffers*/
5289 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5290 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5291 &drv_ctx.ptr_outputbuffer[i];
5292 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5293 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5294 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305295 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5296 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5297 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005298
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005299 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005300 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5301 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5302 // Move the buffer and buffer header pointers
5303 bufHdr++;
5304 pPMEMInfo++;
5305 pPlatformEntry++;
5306 pPlatformList++;
5307 }
5308 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005309 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005310 m_out_mem_ptr, pPtr);
5311 if (m_out_mem_ptr) {
5312 free(m_out_mem_ptr);
5313 m_out_mem_ptr = NULL;
5314 }
5315 if (pPtr) {
5316 free(pPtr);
5317 pPtr = NULL;
5318 }
5319 if (drv_ctx.ptr_outputbuffer) {
5320 free(drv_ctx.ptr_outputbuffer);
5321 drv_ctx.ptr_outputbuffer = NULL;
5322 }
5323 if (drv_ctx.ptr_respbuffer) {
5324 free(drv_ctx.ptr_respbuffer);
5325 drv_ctx.ptr_respbuffer = NULL;
5326 }
5327#ifdef USE_ION
5328 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005329 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005330 free(drv_ctx.op_buf_ion_info);
5331 drv_ctx.op_buf_ion_info = NULL;
5332 }
5333#endif
5334 eRet = OMX_ErrorInsufficientResources;
5335 }
5336 if (eRet == OMX_ErrorNone)
5337 eRet = allocate_extradata();
5338 }
5339
5340 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5341 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005342 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005343 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005344 }
5345 }
Arun Menon906de572013-06-18 17:01:40 -07005346
5347 if (eRet == OMX_ErrorNone) {
5348 if (i < drv_ctx.op_buf.actualcount) {
5349 struct v4l2_buffer buf;
5350 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5351 int rc;
5352 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5353
5354 drv_ctx.ptr_outputbuffer[i].buffer_len =
5355 drv_ctx.op_buf.buffer_size;
5356
5357 *bufferHdr = (m_out_mem_ptr + i );
5358 if (secure_mode) {
5359 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5360 }
5361 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5362
5363 buf.index = i;
5364 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5365 buf.memory = V4L2_MEMORY_USERPTR;
5366 plane[0].length = drv_ctx.op_buf.buffer_size;
5367 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5368 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005369#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005370 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005371#endif
Arun Menon906de572013-06-18 17:01:40 -07005372 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5373 plane[0].data_offset = 0;
5374 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5375 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5376 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5377 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 -07005378#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005379 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005380#endif
Arun Menon906de572013-06-18 17:01:40 -07005381 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5382 plane[extra_idx].data_offset = 0;
5383 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005384 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005385 return OMX_ErrorBadParameter;
5386 }
5387 buf.m.planes = plane;
5388 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005389 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 -07005390 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5391 if (rc) {
5392 /*TODO: How to handle this case */
5393 return OMX_ErrorInsufficientResources;
5394 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005395
Arun Menon906de572013-06-18 17:01:40 -07005396 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5397 enum v4l2_buf_type buf_type;
5398 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5399 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5400 if (rc) {
5401 return OMX_ErrorInsufficientResources;
5402 } else {
5403 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005404 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005405 }
5406 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005407
Arun Menon906de572013-06-18 17:01:40 -07005408 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5409 (*bufferHdr)->pAppPrivate = appData;
5410 BITMASK_SET(&m_out_bm_count,i);
5411 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005412 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005413 eRet = OMX_ErrorInsufficientResources;
5414 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005415 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005416
Arun Menon906de572013-06-18 17:01:40 -07005417 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005418}
5419
5420
5421// AllocateBuffer -- API Call
5422/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005423 FUNCTION
5424 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005425
Arun Menon906de572013-06-18 17:01:40 -07005426 DESCRIPTION
5427 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005428
Arun Menon906de572013-06-18 17:01:40 -07005429 PARAMETERS
5430 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005431
Arun Menon906de572013-06-18 17:01:40 -07005432 RETURN VALUE
5433 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005434
Arun Menon906de572013-06-18 17:01:40 -07005435 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005436OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005437 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5438 OMX_IN OMX_U32 port,
5439 OMX_IN OMX_PTR appData,
5440 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005441{
5442 unsigned i = 0;
5443 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5444
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005445 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005446 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005447 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005448 return OMX_ErrorInvalidState;
5449 }
5450
Arun Menon906de572013-06-18 17:01:40 -07005451 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5452 if (arbitrary_bytes) {
5453 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5454 } else {
5455 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5456 }
5457 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005458 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5459 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005460 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005461 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005462 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005463 }
5464 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005465 if (eRet == OMX_ErrorNone) {
5466 if (allocate_done()) {
5467 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005468 // Send the callback now
5469 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5470 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005471 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005472 }
5473 }
Arun Menon906de572013-06-18 17:01:40 -07005474 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5475 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5476 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5477 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005478 OMX_CORE_INPUT_PORT_INDEX,
5479 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005480 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005481 }
Arun Menon906de572013-06-18 17:01:40 -07005482 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5483 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5484 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005485 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005486 OMX_CORE_OUTPUT_PORT_INDEX,
5487 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005488 }
5489 }
5490 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005491 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005492 return eRet;
5493}
5494
5495// Free Buffer - API call
5496/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005497 FUNCTION
5498 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005499
Arun Menon906de572013-06-18 17:01:40 -07005500 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005501
Arun Menon906de572013-06-18 17:01:40 -07005502 PARAMETERS
5503 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005504
Arun Menon906de572013-06-18 17:01:40 -07005505 RETURN VALUE
5506 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005507
Arun Menon906de572013-06-18 17:01:40 -07005508 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005509OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005510 OMX_IN OMX_U32 port,
5511 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005512{
5513 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5514 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005515 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005516
Arun Menon906de572013-06-18 17:01:40 -07005517 if (m_state == OMX_StateIdle &&
5518 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005519 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005520 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5521 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005522 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005523 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5524 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5525 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5526 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005527 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005528 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005529 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005530 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005531 OMX_ErrorPortUnpopulated,
5532 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005533
5534 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005535 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005536 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005537 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005538 OMX_ErrorPortUnpopulated,
5539 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005540 }
5541
Arun Menon906de572013-06-18 17:01:40 -07005542 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5543 /*Check if arbitrary bytes*/
5544 if (!arbitrary_bytes && !input_use_buffer)
5545 nPortIndex = buffer - m_inp_mem_ptr;
5546 else
5547 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005548
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005549 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005550 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5551 // Clear the bit associated with it.
5552 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5553 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5554 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005555
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005556 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005557 if (m_phdr_pmem_ptr)
5558 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5559 } else {
5560 if (arbitrary_bytes) {
5561 if (m_phdr_pmem_ptr)
5562 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5563 else
5564 free_input_buffer(nPortIndex,NULL);
5565 } else
5566 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005567 }
Arun Menon906de572013-06-18 17:01:40 -07005568 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305569 if(release_input_done())
5570 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005571 /*Free the Buffer Header*/
5572 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005573 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005574 free_input_buffer_header();
5575 }
5576 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005577 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005578 eRet = OMX_ErrorBadPortIndex;
5579 }
5580
Arun Menon906de572013-06-18 17:01:40 -07005581 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5582 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005583 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005584 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5585 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005586 OMX_CORE_INPUT_PORT_INDEX,
5587 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005588 }
Arun Menon906de572013-06-18 17:01:40 -07005589 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005590 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005591 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005592 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005593 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005594 // Clear the bit associated with it.
5595 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5596 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005597 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005598
Surajit Podder12aefac2013-08-06 18:43:32 +05305599 if(release_output_done()) {
5600 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5601 }
Arun Menon906de572013-06-18 17:01:40 -07005602 if (release_output_done()) {
5603 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005604 }
Arun Menon906de572013-06-18 17:01:40 -07005605 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005606 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005607 eRet = OMX_ErrorBadPortIndex;
5608 }
Arun Menon906de572013-06-18 17:01:40 -07005609 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5610 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005611 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005612
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005613 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005614 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005615#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005616 if (m_enable_android_native_buffers) {
5617 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5618 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5619 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005620#endif
5621
Arun Menon906de572013-06-18 17:01:40 -07005622 post_event(OMX_CommandPortDisable,
5623 OMX_CORE_OUTPUT_PORT_INDEX,
5624 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005625 }
Arun Menon906de572013-06-18 17:01:40 -07005626 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005627 eRet = OMX_ErrorBadPortIndex;
5628 }
Arun Menon906de572013-06-18 17:01:40 -07005629 if ((eRet == OMX_ErrorNone) &&
5630 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5631 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005632 // Send the callback now
5633 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5634 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005635 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005636 }
5637 }
5638 return eRet;
5639}
5640
5641
5642/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005643 FUNCTION
5644 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005645
Arun Menon906de572013-06-18 17:01:40 -07005646 DESCRIPTION
5647 This routine is used to push the encoded video frames to
5648 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005649
Arun Menon906de572013-06-18 17:01:40 -07005650 PARAMETERS
5651 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005652
Arun Menon906de572013-06-18 17:01:40 -07005653 RETURN VALUE
5654 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005655
Arun Menon906de572013-06-18 17:01:40 -07005656 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005657OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005658 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005659{
Arun Menon906de572013-06-18 17:01:40 -07005660 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5661 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005662
Arun Menon906de572013-06-18 17:01:40 -07005663 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005664 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005665 return OMX_ErrorInvalidState;
5666 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005667
Arun Menon906de572013-06-18 17:01:40 -07005668 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005669 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005670 return OMX_ErrorBadParameter;
5671 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005672
Arun Menon906de572013-06-18 17:01:40 -07005673 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005674 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005675 return OMX_ErrorIncorrectStateOperation;
5676 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005677
Arun Menon906de572013-06-18 17:01:40 -07005678 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005679 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005680 return OMX_ErrorBadPortIndex;
5681 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005682
5683#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005684 if (iDivXDrmDecrypt) {
5685 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5686 if (drmErr != OMX_ErrorNone) {
5687 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005688 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005689 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005690 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005691#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005692 if (perf_flag) {
5693 if (!latency) {
5694 dec_time.stop();
5695 latency = dec_time.processing_time_us();
5696 dec_time.start();
5697 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005698 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005699
Arun Menon906de572013-06-18 17:01:40 -07005700 if (arbitrary_bytes) {
5701 nBufferIndex = buffer - m_inp_heap_ptr;
5702 } else {
5703 if (input_use_buffer == true) {
5704 nBufferIndex = buffer - m_inp_heap_ptr;
5705 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5706 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5707 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5708 buffer = &m_inp_mem_ptr[nBufferIndex];
5709 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5710 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5711 } else {
5712 nBufferIndex = buffer - m_inp_mem_ptr;
5713 }
5714 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005715
Arun Menon906de572013-06-18 17:01:40 -07005716 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005717 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005718 return OMX_ErrorBadParameter;
5719 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005720
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005721 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5722 codec_config_flag = true;
5723 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5724 }
5725
Arun Menon906de572013-06-18 17:01:40 -07005726 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5727 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5728 if (arbitrary_bytes) {
5729 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005730 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005731 } else {
Arun Menon906de572013-06-18 17:01:40 -07005732 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5733 }
Praveen Chavanece713f2014-12-10 18:00:04 -08005734 time_stamp_dts.insert_timestamp(buffer);
Arun Menon906de572013-06-18 17:01:40 -07005735 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005736}
5737
5738/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005739 FUNCTION
5740 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005741
Arun Menon906de572013-06-18 17:01:40 -07005742 DESCRIPTION
5743 This routine is used to push the encoded video frames to
5744 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005745
Arun Menon906de572013-06-18 17:01:40 -07005746 PARAMETERS
5747 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005748
Arun Menon906de572013-06-18 17:01:40 -07005749 RETURN VALUE
5750 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005751
Arun Menon906de572013-06-18 17:01:40 -07005752 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005753OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005754 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005755{
Arun Menon906de572013-06-18 17:01:40 -07005756 int push_cnt = 0,i=0;
5757 unsigned nPortIndex = 0;
5758 OMX_ERRORTYPE ret = OMX_ErrorNone;
5759 struct vdec_input_frameinfo frameinfo;
5760 struct vdec_bufferpayload *temp_buffer;
5761 struct vdec_seqheader seq_header;
5762 bool port_setting_changed = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005763
Arun Menon906de572013-06-18 17:01:40 -07005764 /*Should we generate a Aync error event*/
5765 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005766 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005767 return OMX_ErrorBadParameter;
5768 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005769
Arun Menon906de572013-06-18 17:01:40 -07005770 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005771
Arun Menon906de572013-06-18 17:01:40 -07005772 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005773 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005774 nPortIndex);
5775 return OMX_ErrorBadParameter;
5776 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005777
Arun Menon906de572013-06-18 17:01:40 -07005778 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005779
Arun Menon906de572013-06-18 17:01:40 -07005780 /* return zero length and not an EOS buffer */
5781 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5782 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005783 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005784 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5785 OMX_COMPONENT_GENERATE_EBD);
5786 return OMX_ErrorNone;
5787 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005788
c_sridur0af9cef2015-02-05 12:07:17 +05305789 if (input_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005790 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005791 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5792 OMX_COMPONENT_GENERATE_EBD);
5793 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005794 }
5795
Arun Menon906de572013-06-18 17:01:40 -07005796 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005797
Surajit Podderd2644d52013-08-28 17:59:06 +05305798 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005799 return OMX_ErrorBadParameter;
5800 }
5801 /* If its first frame, H264 codec and reject is true, then parse the nal
5802 and get the profile. Based on this, reject the clip playback */
5803 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5804 m_reject_avc_1080p_mp) {
5805 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005806 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005807 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5808 NALU_TYPE_SPS);
5809 m_profile = h264_parser->get_profile();
5810 ret = is_video_session_supported();
5811 if (ret) {
5812 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5813 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5814 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5815 m_state = OMX_StateInvalid;
5816 return OMX_ErrorNone;
5817 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005818 }
5819
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005820 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005821 /*for use buffer we need to memcpy the data*/
5822 temp_buffer->buffer_len = buffer->nFilledLen;
5823
5824 if (input_use_buffer) {
5825 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5826 if (arbitrary_bytes) {
5827 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5828 } else {
5829 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5830 buffer->nFilledLen);
5831 }
5832 } else {
5833 return OMX_ErrorBadParameter;
5834 }
5835
5836 }
5837
5838 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5839 frameinfo.client_data = (void *) buffer;
5840 frameinfo.datalen = temp_buffer->buffer_len;
5841 frameinfo.flags = 0;
5842 frameinfo.offset = buffer->nOffset;
5843 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5844 frameinfo.pmem_offset = temp_buffer->offset;
5845 frameinfo.timestamp = buffer->nTimeStamp;
5846 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5847 DEBUG_PRINT_LOW("ETB: dmx enabled");
5848 if (m_demux_entries == 0) {
5849 extract_demux_addr_offsets(buffer);
5850 }
5851
5852 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5853 handle_demux_data(buffer);
5854 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5855 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5856 } else {
5857 frameinfo.desc_addr = NULL;
5858 frameinfo.desc_size = 0;
5859 }
5860 if (!arbitrary_bytes) {
5861 frameinfo.flags |= buffer->nFlags;
5862 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005863
5864#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005865 if (m_debug_timestamp) {
5866 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005867 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005868 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5869 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005870 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005871 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5872 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005873 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005874#endif
5875
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005876log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005877
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005878if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005879 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5880 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5881 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005882
Arun Menon906de572013-06-18 17:01:40 -07005883 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005884 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005885 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5886 h264_scratch.nFilledLen = 0;
5887 nal_count = 0;
5888 look_ahead_nal = false;
5889 frame_count = 0;
5890 if (m_frame_parser.mutils)
5891 m_frame_parser.mutils->initialize_frame_checking_environment();
5892 m_frame_parser.flush();
5893 h264_last_au_ts = LLONG_MAX;
5894 h264_last_au_flags = 0;
5895 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5896 m_demux_entries = 0;
5897 }
5898 struct v4l2_buffer buf;
5899 struct v4l2_plane plane;
5900 memset( (void *)&buf, 0, sizeof(buf));
5901 memset( (void *)&plane, 0, sizeof(plane));
5902 int rc;
5903 unsigned long print_count;
5904 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005905 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005906 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005907 }
5908 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5909 buf.index = nPortIndex;
5910 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5911 buf.memory = V4L2_MEMORY_USERPTR;
5912 plane.bytesused = temp_buffer->buffer_len;
5913 plane.length = drv_ctx.ip_buf.buffer_size;
5914 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5915 (unsigned long)temp_buffer->offset;
5916 plane.reserved[0] = temp_buffer->pmem_fd;
5917 plane.reserved[1] = temp_buffer->offset;
5918 plane.data_offset = 0;
5919 buf.m.planes = &plane;
5920 buf.length = 1;
5921 if (frameinfo.timestamp >= LLONG_MAX) {
5922 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5923 }
5924 //assumption is that timestamp is in milliseconds
5925 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5926 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5927 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5928 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005929
Pushkaraj Patil20bd6bf2014-12-22 19:33:08 +05305930 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5931 DEBUG_PRINT_LOW("Increment codec_config buffer counter");
5932 android_atomic_inc(&m_queued_codec_config_count);
5933 }
5934
Arun Menon906de572013-06-18 17:01:40 -07005935 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5936 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005937 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005938 return OMX_ErrorHardware;
5939 }
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -07005940
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005941 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5942 codec_config_flag = false;
5943 }
Arun Menon906de572013-06-18 17:01:40 -07005944 if (!streaming[OUTPUT_PORT]) {
5945 enum v4l2_buf_type buf_type;
5946 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005947
Arun Menon906de572013-06-18 17:01:40 -07005948 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005949 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005950 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5951 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005952 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005953 streaming[OUTPUT_PORT] = true;
Jia Meng1e236c82014-04-03 10:54:39 +08005954 } else if (errno == EBUSY) {
5955 DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
5956 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
5957 OMX_COMPONENT_GENERATE_EBD);
5958 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005959 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005960 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005961 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
Jia Meng1e236c82014-04-03 10:54:39 +08005962 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
Arun Menon906de572013-06-18 17:01:40 -07005963 OMX_COMPONENT_GENERATE_EBD);
5964 return OMX_ErrorBadParameter;
5965 }
5966 }
5967 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5968 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005969
Arun Menon906de572013-06-18 17:01:40 -07005970 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005971}
5972
5973/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005974 FUNCTION
5975 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005976
Arun Menon906de572013-06-18 17:01:40 -07005977 DESCRIPTION
5978 IL client uses this method to release the frame buffer
5979 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005980
Arun Menon906de572013-06-18 17:01:40 -07005981 PARAMETERS
5982 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005983
Arun Menon906de572013-06-18 17:01:40 -07005984 RETURN VALUE
5985 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005986
Arun Menon906de572013-06-18 17:01:40 -07005987 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005988OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005989 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005990{
Jia Meng2d51b932014-07-10 14:02:54 +08005991 unsigned nPortIndex = 0;
Arun Menonbdb80b02013-08-12 17:45:54 -07005992 if (dynamic_buf_mode) {
5993 private_handle_t *handle = NULL;
5994 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07005995 unsigned int nPortIndex = 0;
5996
5997 if (!buffer || !buffer->pBuffer) {
Arun Menon8544ead2014-05-08 17:42:29 -07005998 DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
Arun Menonbdb80b02013-08-12 17:45:54 -07005999 return OMX_ErrorBadParameter;
6000 }
6001
6002 //get the buffer type and fd info
6003 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
6004 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08006005 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
6006
6007 if (!handle) {
6008 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
6009 return OMX_ErrorBadParameter;
6010 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006011 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
6012 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6013 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08006014 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006015
6016 //Store private handle from GraphicBuffer
6017 native_buffer[nPortIndex].privatehandle = handle;
6018 native_buffer[nPortIndex].nativehandle = handle;
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006019
6020 //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
6021 //this with a more sane size so that we don't compensate in rest of code
6022 //We'll restore this size later on, so that it's transparent to client
6023 buffer->nFilledLen = 0;
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07006024 buffer->nAllocLen = handle->size;
Arun Menonbdb80b02013-08-12 17:45:54 -07006025 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006026
Arun Menon906de572013-06-18 17:01:40 -07006027 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006028 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07006029 return OMX_ErrorInvalidState;
6030 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006031
Arun Menon906de572013-06-18 17:01:40 -07006032 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006033 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07006034 return OMX_ErrorIncorrectStateOperation;
6035 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006036
Jia Meng2d51b932014-07-10 14:02:54 +08006037 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07006038 if (buffer == NULL ||
Jia Meng2d51b932014-07-10 14:02:54 +08006039 (nPortIndex >= drv_ctx.op_buf.actualcount)) {
6040 DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
6041 nPortIndex, drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07006042 return OMX_ErrorBadParameter;
6043 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006044
Arun Menon906de572013-06-18 17:01:40 -07006045 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006046 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07006047 return OMX_ErrorBadPortIndex;
6048 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006049
Arun Menon906de572013-06-18 17:01:40 -07006050 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6051 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
6052 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006053}
6054/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006055 FUNCTION
6056 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07006057
Arun Menon906de572013-06-18 17:01:40 -07006058 DESCRIPTION
6059 IL client uses this method to release the frame buffer
6060 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006061
Arun Menon906de572013-06-18 17:01:40 -07006062 PARAMETERS
6063 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006064
Arun Menon906de572013-06-18 17:01:40 -07006065 RETURN VALUE
6066 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006067
Arun Menon906de572013-06-18 17:01:40 -07006068 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006069OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07006070 OMX_IN OMX_HANDLETYPE hComp,
6071 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006072{
Arun Menon906de572013-06-18 17:01:40 -07006073 OMX_ERRORTYPE nRet = OMX_ErrorNone;
6074 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
6075 unsigned nPortIndex = 0;
6076 struct vdec_fillbuffer_cmd fillbuffer;
6077 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
6078 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006079
Arun Menon906de572013-06-18 17:01:40 -07006080 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07006081
Jia Meng2d51b932014-07-10 14:02:54 +08006082 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) {
6083 DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
6084 nPortIndex, drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07006085 return OMX_ErrorBadParameter;
Jia Meng2d51b932014-07-10 14:02:54 +08006086 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006087
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006088 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006089 bufferAdd, bufferAdd->pBuffer);
6090 /*Return back the output buffer to client*/
6091 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006092 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07006093 buffer->nFilledLen = 0;
6094 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6095 return OMX_ErrorNone;
6096 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08006097
6098 if (dynamic_buf_mode) {
6099 //map the buffer handle based on the size set on output port definition.
6100 if (!secure_mode) {
6101 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
6102 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
6103 PROT_READ|PROT_WRITE, MAP_SHARED,
6104 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
6105 }
6106 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
6107 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
6108 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
6109 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
6110 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
6111 }
6112
Arun Menon906de572013-06-18 17:01:40 -07006113 pending_output_buffers++;
6114 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
6115 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
6116 if (ptr_respbuffer) {
6117 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
6118 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006119
Arun Menon906de572013-06-18 17:01:40 -07006120 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
6121 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
6122 buffer->nFilledLen = 0;
6123 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6124 pending_output_buffers--;
6125 return OMX_ErrorBadParameter;
6126 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006127
Arun Menon906de572013-06-18 17:01:40 -07006128 int rc = 0;
6129 struct v4l2_buffer buf;
6130 struct v4l2_plane plane[VIDEO_MAX_PLANES];
6131 memset( (void *)&buf, 0, sizeof(buf));
6132 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Arun Menon8544ead2014-05-08 17:42:29 -07006133 unsigned int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006134
Arun Menon906de572013-06-18 17:01:40 -07006135 buf.index = nPortIndex;
6136 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6137 buf.memory = V4L2_MEMORY_USERPTR;
6138 plane[0].bytesused = buffer->nFilledLen;
6139 plane[0].length = drv_ctx.op_buf.buffer_size;
6140 plane[0].m.userptr =
6141 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
6142 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6143 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
6144 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6145 plane[0].data_offset = 0;
6146 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
6147 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
6148 plane[extra_idx].bytesused = 0;
6149 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
6150 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 -07006151#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07006152 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006153#endif
Arun Menon906de572013-06-18 17:01:40 -07006154 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
6155 plane[extra_idx].data_offset = 0;
6156 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Arun Menon8544ead2014-05-08 17:42:29 -07006157 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07006158 return OMX_ErrorBadParameter;
6159 }
6160 buf.m.planes = plane;
6161 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006162 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07006163 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
6164
Arun Menon906de572013-06-18 17:01:40 -07006165 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6166 if (rc) {
6167 /*TODO: How to handle this case */
6168 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6169 }
Arun Menon906de572013-06-18 17:01:40 -07006170return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006171}
6172
6173/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006174 FUNCTION
6175 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07006176
Arun Menon906de572013-06-18 17:01:40 -07006177 DESCRIPTION
6178 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006179
Arun Menon906de572013-06-18 17:01:40 -07006180 PARAMETERS
6181 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006182
Arun Menon906de572013-06-18 17:01:40 -07006183 RETURN VALUE
6184 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006185
Arun Menon906de572013-06-18 17:01:40 -07006186 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006187OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006188 OMX_IN OMX_CALLBACKTYPE* callbacks,
6189 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006190{
6191
Arun Menon906de572013-06-18 17:01:40 -07006192 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006193 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07006194 m_cb.EventHandler,m_cb.FillBufferDone);
6195 m_app_data = appData;
6196 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006197}
6198
6199/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006200 FUNCTION
6201 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07006202
Arun Menon906de572013-06-18 17:01:40 -07006203 DESCRIPTION
6204 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006205
Arun Menon906de572013-06-18 17:01:40 -07006206 PARAMETERS
6207 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006208
Arun Menon906de572013-06-18 17:01:40 -07006209 RETURN VALUE
6210 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006211
Arun Menon906de572013-06-18 17:01:40 -07006212 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006213OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6214{
6215#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006216 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006217 delete iDivXDrmDecrypt;
6218 iDivXDrmDecrypt=NULL;
6219 }
6220#endif //_ANDROID_
6221
Shalaj Jain286b0062013-02-21 20:35:48 -08006222 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07006223 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006224 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07006225 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006226 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07006227 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006228 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006229 }
6230
6231 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006232 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006233 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07006234 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
6235 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006236 }
6237#ifdef _ANDROID_ICS_
6238 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6239#endif
6240 }
6241
6242 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006243 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006244 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07006245 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
6246 if (m_inp_mem_ptr)
6247 free_input_buffer (i,&m_inp_mem_ptr[i]);
6248 else
6249 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006250 }
6251 }
6252 free_input_buffer_header();
6253 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07006254 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006255 free(h264_scratch.pBuffer);
6256 h264_scratch.pBuffer = NULL;
6257 }
6258
Arun Menon906de572013-06-18 17:01:40 -07006259 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006260 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07006261 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006262 }
6263
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006264 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006265 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006266 delete (m_frame_parser.mutils);
6267 m_frame_parser.mutils = NULL;
6268 }
6269
Arun Menon906de572013-06-18 17:01:40 -07006270 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006271 free(m_platform_list);
6272 m_platform_list = NULL;
6273 }
Arun Menon906de572013-06-18 17:01:40 -07006274 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006275 free(m_vendor_config.pData);
6276 m_vendor_config.pData = NULL;
6277 }
6278
6279 // Reset counters in mesg queues
6280 m_ftb_q.m_size=0;
6281 m_cmd_q.m_size=0;
6282 m_etb_q.m_size=0;
6283 m_ftb_q.m_read = m_ftb_q.m_write =0;
6284 m_cmd_q.m_read = m_cmd_q.m_write =0;
6285 m_etb_q.m_read = m_etb_q.m_write =0;
6286#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006287 if (m_debug_timestamp) {
6288 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006289 }
6290#endif
6291
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006292 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006293 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006294 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006295 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006296
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006297 if (m_debug.infile) {
6298 fclose(m_debug.infile);
6299 m_debug.infile = NULL;
6300 }
6301 if (m_debug.outfile) {
6302 fclose(m_debug.outfile);
6303 m_debug.outfile = NULL;
6304 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006305#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006306 if (outputExtradataFile)
6307 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006308#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006309 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006310 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006311}
6312
6313/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006314 FUNCTION
6315 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006316
Arun Menon906de572013-06-18 17:01:40 -07006317 DESCRIPTION
6318 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006319
Arun Menon906de572013-06-18 17:01:40 -07006320 PARAMETERS
6321 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006322
Arun Menon906de572013-06-18 17:01:40 -07006323 RETURN VALUE
6324 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006325
Arun Menon906de572013-06-18 17:01:40 -07006326 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006327OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006328 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6329 OMX_IN OMX_U32 port,
6330 OMX_IN OMX_PTR appData,
6331 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006332{
Arun Menon906de572013-06-18 17:01:40 -07006333 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6334 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6335 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006336
6337#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006338 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6339 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006340#else
Arun Menon906de572013-06-18 17:01:40 -07006341 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006342#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006343 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006344 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006345 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006346 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006347#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006348 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006349 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006350 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006351 }
6352 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6353 eglGetProcAddress("eglQueryImageKHR");
6354 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6355 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6356 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006357#else //with OMX test app
6358 struct temp_egl {
6359 int pmem_fd;
6360 int offset;
6361 };
6362 struct temp_egl *temp_egl_id = NULL;
6363 void * pmemPtr = (void *) eglImage;
6364 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006365 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006366 fd = temp_egl_id->pmem_fd;
6367 offset = temp_egl_id->offset;
6368 }
6369#endif
6370 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006371 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006372 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006373 }
6374 pmem_info.pmem_fd = (OMX_U32) fd;
6375 pmem_info.offset = (OMX_U32) offset;
6376 pmem_entry.entry = (void *) &pmem_info;
6377 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6378 pmem_list.entryList = &pmem_entry;
6379 pmem_list.nEntries = 1;
6380 ouput_egl_buffers = true;
6381 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6382 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6383 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006384 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006385 return OMX_ErrorInsufficientResources;
6386 }
6387 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006388}
6389
6390/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006391 FUNCTION
6392 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006393
Arun Menon906de572013-06-18 17:01:40 -07006394 DESCRIPTION
6395 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006396
Arun Menon906de572013-06-18 17:01:40 -07006397 PARAMETERS
6398 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006399
Arun Menon906de572013-06-18 17:01:40 -07006400 RETURN VALUE
6401 OMX Error None if everything is successful.
6402 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006403OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006404 OMX_OUT OMX_U8* role,
6405 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006406{
Arun Menon906de572013-06-18 17:01:40 -07006407 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006408
Arun Menon906de572013-06-18 17:01:40 -07006409 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6410 if ((0 == index) && role) {
6411 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006412 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006413 } else {
6414 eRet = OMX_ErrorNoMore;
6415 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006416 }
Arun Menon906de572013-06-18 17:01:40 -07006417 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6418 if ((0 == index) && role) {
6419 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006420 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006421 } else {
6422 eRet = OMX_ErrorNoMore;
6423 }
6424 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6425 if ((0 == index) && role) {
6426 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006427 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006428 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006429 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006430 eRet = OMX_ErrorNoMore;
6431 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006432 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006433
Arun Menon906de572013-06-18 17:01:40 -07006434 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6435 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6436 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006437
Shalaj Jain273b3e02012-06-22 19:08:03 -07006438 {
Arun Menon906de572013-06-18 17:01:40 -07006439 if ((0 == index) && role) {
6440 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006441 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006442 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006443 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006444 eRet = OMX_ErrorNoMore;
6445 }
6446 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6447 if ((0 == index) && role) {
6448 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006449 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006450 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006451 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006452 eRet = OMX_ErrorNoMore;
6453 }
6454 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6455 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6456 ) {
6457 if ((0 == index) && role) {
6458 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006459 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006460 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006461 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006462 eRet = OMX_ErrorNoMore;
6463 }
6464 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6465 if ((0 == index) && role) {
6466 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006467 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006468 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006469 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006470 eRet = OMX_ErrorNoMore;
6471 }
6472 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006473 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006474 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006475 }
Arun Menon906de572013-06-18 17:01:40 -07006476 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006477}
6478
6479
6480
6481
6482/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006483 FUNCTION
6484 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006485
Arun Menon906de572013-06-18 17:01:40 -07006486 DESCRIPTION
6487 Checks if entire buffer pool is allocated by IL Client or not.
6488 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006489
Arun Menon906de572013-06-18 17:01:40 -07006490 PARAMETERS
6491 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006492
Arun Menon906de572013-06-18 17:01:40 -07006493 RETURN VALUE
6494 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006495
Arun Menon906de572013-06-18 17:01:40 -07006496 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006497bool omx_vdec::allocate_done(void)
6498{
Arun Menon906de572013-06-18 17:01:40 -07006499 bool bRet = false;
6500 bool bRet_In = false;
6501 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006502
Arun Menon906de572013-06-18 17:01:40 -07006503 bRet_In = allocate_input_done();
6504 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006505
Arun Menon906de572013-06-18 17:01:40 -07006506 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006507 bRet = true;
6508 }
Arun Menon906de572013-06-18 17:01:40 -07006509
6510 return bRet;
6511}
6512/* ======================================================================
6513 FUNCTION
6514 omx_vdec::AllocateInputDone
6515
6516 DESCRIPTION
6517 Checks if I/P buffer pool is allocated by IL Client or not.
6518
6519 PARAMETERS
6520 None.
6521
6522 RETURN VALUE
6523 true/false.
6524
6525 ========================================================================== */
6526bool omx_vdec::allocate_input_done(void)
6527{
6528 bool bRet = false;
6529 unsigned i=0;
6530
6531 if (m_inp_mem_ptr == NULL) {
6532 return bRet;
6533 }
6534 if (m_inp_mem_ptr ) {
6535 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6536 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6537 break;
6538 }
6539 }
6540 }
6541 if (i == drv_ctx.ip_buf.actualcount) {
6542 bRet = true;
6543 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6544 }
6545 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6546 m_inp_bPopulated = OMX_TRUE;
6547 }
6548 return bRet;
6549}
6550/* ======================================================================
6551 FUNCTION
6552 omx_vdec::AllocateOutputDone
6553
6554 DESCRIPTION
6555 Checks if entire O/P buffer pool is allocated by IL Client or not.
6556
6557 PARAMETERS
6558 None.
6559
6560 RETURN VALUE
6561 true/false.
6562
6563 ========================================================================== */
6564bool omx_vdec::allocate_output_done(void)
6565{
6566 bool bRet = false;
6567 unsigned j=0;
6568
6569 if (m_out_mem_ptr == NULL) {
6570 return bRet;
6571 }
6572
6573 if (m_out_mem_ptr) {
6574 for (; j < drv_ctx.op_buf.actualcount; j++) {
6575 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6576 break;
6577 }
6578 }
6579 }
6580
6581 if (j == drv_ctx.op_buf.actualcount) {
6582 bRet = true;
6583 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6584 if (m_out_bEnabled)
6585 m_out_bPopulated = OMX_TRUE;
6586 }
6587
6588 return bRet;
6589}
6590
6591/* ======================================================================
6592 FUNCTION
6593 omx_vdec::ReleaseDone
6594
6595 DESCRIPTION
6596 Checks if IL client has released all the buffers.
6597
6598 PARAMETERS
6599 None.
6600
6601 RETURN VALUE
6602 true/false
6603
6604 ========================================================================== */
6605bool omx_vdec::release_done(void)
6606{
6607 bool bRet = false;
6608
6609 if (release_input_done()) {
6610 if (release_output_done()) {
6611 bRet = true;
6612 }
6613 }
6614 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006615}
6616
6617
6618/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006619 FUNCTION
6620 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006621
Arun Menon906de572013-06-18 17:01:40 -07006622 DESCRIPTION
6623 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006624
Arun Menon906de572013-06-18 17:01:40 -07006625 PARAMETERS
6626 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006627
Arun Menon906de572013-06-18 17:01:40 -07006628 RETURN VALUE
6629 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006630
Arun Menon906de572013-06-18 17:01:40 -07006631 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006632bool omx_vdec::release_output_done(void)
6633{
Arun Menon906de572013-06-18 17:01:40 -07006634 bool bRet = false;
6635 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006636
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006637 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006638 if (m_out_mem_ptr) {
6639 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6640 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6641 break;
6642 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006643 }
Arun Menon906de572013-06-18 17:01:40 -07006644 if (j == drv_ctx.op_buf.actualcount) {
6645 m_out_bm_count = 0;
6646 bRet = true;
6647 }
6648 } else {
6649 m_out_bm_count = 0;
6650 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006651 }
Arun Menon906de572013-06-18 17:01:40 -07006652 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006653}
6654/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006655 FUNCTION
6656 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006657
Arun Menon906de572013-06-18 17:01:40 -07006658 DESCRIPTION
6659 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006660
Arun Menon906de572013-06-18 17:01:40 -07006661 PARAMETERS
6662 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006663
Arun Menon906de572013-06-18 17:01:40 -07006664 RETURN VALUE
6665 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006666
Arun Menon906de572013-06-18 17:01:40 -07006667 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006668bool omx_vdec::release_input_done(void)
6669{
Arun Menon906de572013-06-18 17:01:40 -07006670 bool bRet = false;
6671 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006672
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006673 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006674 if (m_inp_mem_ptr) {
6675 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6676 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6677 break;
6678 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006679 }
Arun Menon906de572013-06-18 17:01:40 -07006680 if (j==drv_ctx.ip_buf.actualcount) {
6681 bRet = true;
6682 }
6683 } else {
6684 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006685 }
Arun Menon906de572013-06-18 17:01:40 -07006686 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006687}
6688
6689OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006690 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006691{
Arun Menon906de572013-06-18 17:01:40 -07006692 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306693 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006694 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006695 return OMX_ErrorBadParameter;
6696 } else if (output_flush_progress) {
6697 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6698 buffer->nFilledLen = 0;
6699 buffer->nTimeStamp = 0;
6700 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6701 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6702 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006703 }
6704
Arun Menon906de572013-06-18 17:01:40 -07006705 if (m_debug_extradata) {
6706 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006707 DEBUG_PRINT_HIGH("");
6708 DEBUG_PRINT_HIGH("***************************************************");
6709 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6710 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006711 }
6712
6713 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006714 DEBUG_PRINT_HIGH("");
6715 DEBUG_PRINT_HIGH("***************************************************");
6716 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6717 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006718 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006719 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006720
6721
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006722 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006723 buffer, buffer->pBuffer);
6724 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006725
Arun Menon906de572013-06-18 17:01:40 -07006726 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006727 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006728 if (!output_flush_progress)
6729 post_event((unsigned)NULL, (unsigned)NULL,
6730 OMX_COMPONENT_GENERATE_EOS_DONE);
6731
6732 if (psource_frame) {
6733 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6734 psource_frame = NULL;
6735 }
6736 if (pdest_frame) {
6737 pdest_frame->nFilledLen = 0;
6738 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6739 (unsigned)NULL);
6740 pdest_frame = NULL;
6741 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006742 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006743
Shalaj Jain273b3e02012-06-22 19:08:03 -07006744
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006745 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6746 DEBUG_PRINT_LOW("Processing extradata");
6747 handle_extradata(buffer);
6748 }
6749
Arun Menon906de572013-06-18 17:01:40 -07006750 /* For use buffer we need to copy the data */
6751 if (!output_flush_progress) {
6752 /* This is the error check for non-recoverable errros */
6753 bool is_duplicate_ts_valid = true;
6754 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006755
Arun Menon906de572013-06-18 17:01:40 -07006756 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6757 output_capability == V4L2_PIX_FMT_MPEG2 ||
6758 output_capability == V4L2_PIX_FMT_DIVX ||
6759 output_capability == V4L2_PIX_FMT_DIVX_311)
6760 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006761
Arun Menon906de572013-06-18 17:01:40 -07006762 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
Arun Menon7b6fd642014-02-13 16:48:36 -08006763 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
Arun Menon906de572013-06-18 17:01:40 -07006764 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306765 }
Arun Menon906de572013-06-18 17:01:40 -07006766 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306767
Arun Menon906de572013-06-18 17:01:40 -07006768 if (buffer->nFilledLen > 0) {
6769 time_stamp_dts.get_next_timestamp(buffer,
6770 is_interlaced && is_duplicate_ts_valid);
6771 if (m_debug_timestamp) {
6772 {
6773 OMX_TICKS expected_ts = 0;
6774 m_timestamp_list.pop_min_ts(expected_ts);
6775 if (is_interlaced && is_duplicate_ts_valid) {
6776 m_timestamp_list.pop_min_ts(expected_ts);
6777 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006778 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006779 buffer->nTimeStamp, expected_ts);
6780
6781 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006782 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006783 }
6784 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306785 }
Arun Menon906de572013-06-18 17:01:40 -07006786 } else {
Arun Menon906de572013-06-18 17:01:40 -07006787 time_stamp_dts.remove_time_stamp(
6788 buffer->nTimeStamp,
6789 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306790 }
Arun Menon906de572013-06-18 17:01:40 -07006791
6792
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006793 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006794
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006795 /* Since we're passing around handles, adjust nFilledLen and nAllocLen
6796 * to size of the handle. Do it _after_ handle_extradata() which
6797 * requires the respective sizes to be accurate. */
6798 if (dynamic_buf_mode) {
6799 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
6800 buffer->nFilledLen = buffer->nFilledLen ?
6801 sizeof(struct VideoDecoderOutputMetaData) : 0;
6802 }
6803
Arun Menon906de572013-06-18 17:01:40 -07006804 if (m_cb.FillBufferDone) {
6805 if (buffer->nFilledLen > 0) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006806 if (arbitrary_bytes)
Arun Menon906de572013-06-18 17:01:40 -07006807 adjust_timestamp(buffer->nTimeStamp);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006808 else
6809 set_frame_rate(buffer->nTimeStamp);
6810
Arun Menon906de572013-06-18 17:01:40 -07006811 if (perf_flag) {
6812 if (!proc_frms) {
6813 dec_time.stop();
6814 latency = dec_time.processing_time_us() - latency;
6815 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6816 dec_time.start();
6817 fps_metrics.start();
6818 }
6819 proc_frms++;
6820 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6821 OMX_U64 proc_time = 0;
6822 fps_metrics.stop();
6823 proc_time = fps_metrics.processing_time_us();
6824 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006825 proc_frms, (float)proc_time / 1e6,
6826 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006827 proc_frms = 0;
6828 }
6829 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006830
6831#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006832 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006833
Arun Menon906de572013-06-18 17:01:40 -07006834 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6835 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6836 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6837 buffer->nFilledLen + 3)&(~3));
6838 while (p_extra &&
6839 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006840 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006841 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6842 if (p_extra->eType == OMX_ExtraDataNone) {
6843 break;
6844 }
6845 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6846 }
6847 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006848#endif
Arun Menon906de572013-06-18 17:01:40 -07006849 }
6850 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6851 prev_ts = LLONG_MAX;
6852 rst_prev_ts = true;
6853 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006854
Arun Menon906de572013-06-18 17:01:40 -07006855 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6856 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6857 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006858 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006859 OMX_BUFFERHEADERTYPE *il_buffer;
6860 il_buffer = client_buffers.get_il_buf_hdr(buffer);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006861
vivek mehta79cff222014-01-22 12:17:07 -08006862 if (il_buffer && m_last_rendered_TS >= 0) {
6863 int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
Manikanta Kanamarlapudifb53b262014-01-20 16:12:47 +05306864 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
vivek mehta79cff222014-01-22 12:17:07 -08006865
6866 // Current frame can be send for rendering if
6867 // (a) current FPS is <= 60
6868 // (b) is the next frame after the frame with TS 0
6869 // (c) is the first frame after seek
6870 // (d) the delta TS b\w two consecutive frames is > 16 ms
6871 // (e) its TS is equal to previous frame TS
6872 // (f) if marked EOS
6873
6874 if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
6875 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
6876 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006877 m_last_rendered_TS = il_buffer->nTimeStamp;
vivek mehta79cff222014-01-22 12:17:07 -08006878 } else {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006879 //mark for droping
vivek mehtaa75c69f2014-01-10 21:50:37 -08006880 buffer->nFilledLen = 0;
vivek mehta79cff222014-01-22 12:17:07 -08006881 }
6882
6883 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%d)",
6884 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
6885 il_buffer->nTimeStamp,ts_delta);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006886 }
6887
vivek mehta79cff222014-01-22 12:17:07 -08006888 if (il_buffer) {
Arun Menon9230eb82014-02-11 19:19:02 -08006889 log_output_buffers(il_buffer);
6890 if (dynamic_buf_mode) {
6891 unsigned int nPortIndex = 0;
6892 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6893
6894 if (!secure_mode) {
6895 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6896 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6897 }
6898
6899 //Clear graphic buffer handles in dynamic mode
6900 native_buffer[nPortIndex].privatehandle = NULL;
6901 native_buffer[nPortIndex].nativehandle = NULL;
6902 }
Arun Menon906de572013-06-18 17:01:40 -07006903 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
vivek mehta79cff222014-01-22 12:17:07 -08006904 } else {
Arun Menon906de572013-06-18 17:01:40 -07006905 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6906 return OMX_ErrorBadParameter;
6907 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006908 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006909 } else {
6910 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006911 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006912
Praveen Chavancf924182013-12-06 23:16:23 -08006913#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306914 if (m_smoothstreaming_mode && m_out_mem_ptr) {
Praveen Chavancf924182013-12-06 23:16:23 -08006915 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6916 BufferDim_t dim;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306917 private_handle_t *private_handle = NULL;
Pushkaraj Patil065b5732014-11-26 11:08:02 +05306918 dim.sliceWidth = framesize.nWidth;
6919 dim.sliceHeight = framesize.nHeight;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306920 if (native_buffer[buf_index].privatehandle)
6921 private_handle = native_buffer[buf_index].privatehandle;
Praveen Chavancf924182013-12-06 23:16:23 -08006922 if (private_handle) {
6923 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6924 dim.sliceWidth, dim.sliceHeight);
6925 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6926 }
6927 }
6928#endif
6929
Arun Menon906de572013-06-18 17:01:40 -07006930 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006931}
6932
6933OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006934 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006935{
6936
Surajit Podderd2644d52013-08-28 17:59:06 +05306937 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006938 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006939 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006940 }
6941
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006942 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006943 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006944 pending_input_buffers--;
6945
Arun Menon906de572013-06-18 17:01:40 -07006946 if (arbitrary_bytes) {
6947 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006948 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006949 pdest_frame = buffer;
6950 buffer->nFilledLen = 0;
6951 buffer->nTimeStamp = LLONG_MAX;
6952 push_input_buffer (hComp);
6953 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006954 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006955 buffer->nFilledLen = 0;
6956 if (!m_input_free_q.insert_entry((unsigned)buffer,
6957 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006958 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006959 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006960 }
Arun Menon906de572013-06-18 17:01:40 -07006961 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006962 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006963 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006964 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6965 }
6966 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6967 }
6968 return OMX_ErrorNone;
6969}
6970
Shalaj Jain273b3e02012-06-22 19:08:03 -07006971int omx_vdec::async_message_process (void *context, void* message)
6972{
Arun Menon906de572013-06-18 17:01:40 -07006973 omx_vdec* omx = NULL;
6974 struct vdec_msginfo *vdec_msg = NULL;
6975 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6976 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6977 struct vdec_output_frameinfo *output_respbuf = NULL;
6978 int rc=1;
6979 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006980 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006981 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006982 }
Arun Menon906de572013-06-18 17:01:40 -07006983 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006984
Arun Menon906de572013-06-18 17:01:40 -07006985 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006986
Arun Menon906de572013-06-18 17:01:40 -07006987 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006988
Arun Menon906de572013-06-18 17:01:40 -07006989 case VDEC_MSG_EVT_HW_ERROR:
6990 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6991 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6992 break;
6993
Deepak Verma24720fb2014-01-29 16:57:40 +05306994 case VDEC_MSG_EVT_HW_OVERLOAD:
6995 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6996 OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
6997 break;
6998
Arun Menon906de572013-06-18 17:01:40 -07006999 case VDEC_MSG_RESP_START_DONE:
7000 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7001 OMX_COMPONENT_GENERATE_START_DONE);
7002 break;
7003
7004 case VDEC_MSG_RESP_STOP_DONE:
7005 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7006 OMX_COMPONENT_GENERATE_STOP_DONE);
7007 break;
7008
7009 case VDEC_MSG_RESP_RESUME_DONE:
7010 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7011 OMX_COMPONENT_GENERATE_RESUME_DONE);
7012 break;
7013
7014 case VDEC_MSG_RESP_PAUSE_DONE:
7015 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7016 OMX_COMPONENT_GENERATE_PAUSE_DONE);
7017 break;
7018
7019 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
7020 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7021 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
7022 break;
7023 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
7024 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7025 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
7026 break;
7027 case VDEC_MSG_RESP_INPUT_FLUSHED:
7028 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
7029
7030 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
7031 vdec_msg->msgdata.input_frame_clientdata; */
7032
7033 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
7034 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
7035 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05307036 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07007037 omxhdr = NULL;
7038 vdec_msg->status_code = VDEC_S_EFATAL;
7039 }
7040 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
7041 DEBUG_PRINT_HIGH("Unsupported input");
7042 omx->omx_report_error ();
7043 }
7044 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
7045 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
7046 }
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307047 if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307048
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05307049 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
7050 android_atomic_dec(&omx->m_queued_codec_config_count);
7051 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
7052 BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
7053 DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307054 sem_post(&omx->m_safe_flush);
7055 }
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307056 }
7057
Arun Menon906de572013-06-18 17:01:40 -07007058 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
7059 OMX_COMPONENT_GENERATE_EBD);
7060 break;
7061 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
7062 int64_t *timestamp;
7063 timestamp = (int64_t *) malloc(sizeof(int64_t));
7064 if (timestamp) {
7065 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
7066 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
7067 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007068 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07007069 vdec_msg->msgdata.output_frame.time_stamp);
7070 }
7071 break;
7072 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
7073 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
7074
7075 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
7076 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307077
7078 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x) FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)",
Arun Menon906de572013-06-18 17:01:40 -07007079 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307080 vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
7081 (unsigned int)vdec_msg->msgdata.output_frame.len,
7082 vdec_msg->msgdata.output_frame.framesize.left,
7083 vdec_msg->msgdata.output_frame.framesize.top,
7084 vdec_msg->msgdata.output_frame.framesize.right,
7085 vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07007086
7087 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05307088 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07007089 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05307090 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307091
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07007092 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
Arun Menon906de572013-06-18 17:01:40 -07007093 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
7094 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
7095 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
7096 omxhdr->nFlags = 0;
7097
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07007098 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07007099 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
7100 //rc = -1;
7101 }
7102 if (omxhdr->nFilledLen) {
7103 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
7104 }
7105 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
7106 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
7107 } else {
7108 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
7109 }
7110 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
7111 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7112 }
7113 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
7114 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
7115 }
Arun Menon7b6fd642014-02-13 16:48:36 -08007116
7117 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
7118 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
7119 }
7120
Arun Menonbdb80b02013-08-12 17:45:54 -07007121 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07007122 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07007123 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
7124 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
7125 }
Arun Menonbdb80b02013-08-12 17:45:54 -07007126 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
7127 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
7128 omxhdr->nOffset);
7129 }
Arun Menon906de572013-06-18 17:01:40 -07007130 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
7131 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07007132 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07007133 omx->time_stamp_dts.remove_time_stamp(
7134 omxhdr->nTimeStamp,
7135 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
7136 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07007137 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
7138 OMX_COMPONENT_GENERATE_FTB);
7139 break;
7140 }
7141 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
7142 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7143 }
7144 vdec_msg->msgdata.output_frame.bufferaddr =
7145 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307146
7147 /* Post event if resolution OR crop changed */
7148 /* filled length will be changed if resolution changed */
7149 /* Crop parameters can be changed even without resolution change */
7150 if (omxhdr->nFilledLen
7151 && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
7152 || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
7153 || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
7154 || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05307155 || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
7156 || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
7157 || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307158
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05307159 DEBUG_PRINT_HIGH("Paramters Changed From: Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u --> Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u",
7160 omx->prev_n_filled_len,
7161 omx->drv_ctx.video_resolution.frame_width,
7162 omx->drv_ctx.video_resolution.frame_height,
7163 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
7164 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
7165 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
7166 vdec_msg->msgdata.output_frame.picsize.frame_height,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307167 vdec_msg->msgdata.output_frame.framesize.left,
7168 vdec_msg->msgdata.output_frame.framesize.top,
7169 vdec_msg->msgdata.output_frame.framesize.right,
7170 vdec_msg->msgdata.output_frame.framesize.bottom);
7171
Maheshwar Ajja0f840ce2014-09-29 16:53:42 +05307172 omx->drv_ctx.video_resolution.frame_width =
7173 vdec_msg->msgdata.output_frame.picsize.frame_width;
7174 omx->drv_ctx.video_resolution.frame_height =
7175 vdec_msg->msgdata.output_frame.picsize.frame_height;
Praneeth Paladuguca80be72014-10-22 23:48:54 -07007176 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
7177 omx->drv_ctx.video_resolution.stride =
7178 VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
7179 omx->drv_ctx.video_resolution.scan_lines =
7180 VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
7181 }
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307182 memcpy(&omx->drv_ctx.frame_size,
7183 &vdec_msg->msgdata.output_frame.framesize,
7184 sizeof(struct vdec_framesize));
7185
7186 omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
7187 OMX_IndexConfigCommonOutputCrop,
7188 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Arun Menon906de572013-06-18 17:01:40 -07007189 }
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307190
Arun Menon906de572013-06-18 17:01:40 -07007191 if (omxhdr->nFilledLen)
7192 omx->prev_n_filled_len = omxhdr->nFilledLen;
7193
7194 output_respbuf = (struct vdec_output_frameinfo *)\
7195 omxhdr->pOutputPortPrivate;
7196 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7197 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307198
Arun Menon906de572013-06-18 17:01:40 -07007199 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
7200 output_respbuf->pic_type = PICTURE_TYPE_I;
7201 }
7202 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
7203 output_respbuf->pic_type = PICTURE_TYPE_P;
7204 }
7205 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7206 output_respbuf->pic_type = PICTURE_TYPE_B;
7207 }
7208
7209 if (omx->output_use_buffer)
7210 memcpy ( omxhdr->pBuffer, (void *)
7211 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7212 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7213 vdec_msg->msgdata.output_frame.len);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307214 } else {
7215 DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
7216 (unsigned int)vdec_msg->msgdata.output_frame.len,
7217 omxhdr->nAllocLen, omx->prev_n_filled_len);
Arun Menon906de572013-06-18 17:01:40 -07007218 omxhdr->nFilledLen = 0;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307219 }
7220
Arun Menon906de572013-06-18 17:01:40 -07007221 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7222 OMX_COMPONENT_GENERATE_FBD);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307223
7224 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07007225 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7226 OMX_COMPONENT_GENERATE_EOS_DONE);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307227 } else {
Arun Menon906de572013-06-18 17:01:40 -07007228 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7229 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307230 }
Arun Menon906de572013-06-18 17:01:40 -07007231 break;
7232 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007233 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07007234 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7235 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7236 break;
7237 default:
7238 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007239 }
Arun Menon906de572013-06-18 17:01:40 -07007240 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007241}
7242
7243OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07007244 OMX_HANDLETYPE hComp,
7245 OMX_BUFFERHEADERTYPE *buffer
7246 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07007247{
Arun Menon906de572013-06-18 17:01:40 -07007248 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007249 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007250
Arun Menon906de572013-06-18 17:01:40 -07007251 if (buffer == NULL) {
7252 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007253 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007254 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7255 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007256 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
7257
7258 /* return zero length and not an EOS buffer */
7259 /* return buffer if input flush in progress */
7260 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7261 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007262 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07007263 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7264 return OMX_ErrorNone;
7265 }
7266
7267 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007268 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007269 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007270 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07007271 push_input_buffer (hComp);
7272 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007273 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07007274 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7275 (unsigned)NULL)) {
7276 return OMX_ErrorBadParameter;
7277 }
7278 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007279
Sowmya Pandiri302f5ab2014-04-03 13:41:03 -07007280 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
7281 codec_config_flag = false;
7282 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007283
Arun Menon906de572013-06-18 17:01:40 -07007284 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007285}
7286
7287OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7288{
Arun Menon906de572013-06-18 17:01:40 -07007289 unsigned address,p2,id;
7290 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007291
Arun Menon906de572013-06-18 17:01:40 -07007292 if (pdest_frame == NULL || psource_frame == NULL) {
7293 /*Check if we have a destination buffer*/
7294 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007295 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007296 if (m_input_free_q.m_size) {
7297 m_input_free_q.pop_entry(&address,&p2,&id);
7298 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7299 pdest_frame->nFilledLen = 0;
7300 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007301 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007302 }
7303 }
7304
7305 /*Check if we have a destination buffer*/
7306 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007307 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007308 if (m_input_pending_q.m_size) {
7309 m_input_pending_q.pop_entry(&address,&p2,&id);
7310 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007311 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007312 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007313 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007314 psource_frame->nFlags,psource_frame->nFilledLen);
7315
7316 }
7317 }
7318
Shalaj Jain273b3e02012-06-22 19:08:03 -07007319 }
7320
Arun Menon906de572013-06-18 17:01:40 -07007321 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7322 switch (codec_type_parse) {
7323 case CODEC_TYPE_MPEG4:
7324 case CODEC_TYPE_H263:
7325 case CODEC_TYPE_MPEG2:
7326 ret = push_input_sc_codec(hComp);
7327 break;
7328 case CODEC_TYPE_H264:
7329 ret = push_input_h264(hComp);
7330 break;
7331 case CODEC_TYPE_VC1:
7332 ret = push_input_vc1(hComp);
7333 break;
7334 default:
7335 break;
7336 }
7337 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007338 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007339 omx_report_error ();
7340 break;
7341 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007342 }
7343
Arun Menon906de572013-06-18 17:01:40 -07007344 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007345}
7346
7347OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7348{
Arun Menon906de572013-06-18 17:01:40 -07007349 OMX_U32 partial_frame = 1;
7350 OMX_BOOL generate_ebd = OMX_TRUE;
7351 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007352
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007353 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007354 psource_frame,psource_frame->nTimeStamp);
7355 if (m_frame_parser.parse_sc_frame(psource_frame,
7356 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007357 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007358 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007359 }
Arun Menon906de572013-06-18 17:01:40 -07007360
7361 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007362 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007363 pdest_frame->nFilledLen,psource_frame,frame_count);
7364
7365
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007366 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007367 /*First Parsed buffer will have only header Hence skip*/
7368 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007369 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007370
7371 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7372 codec_type_parse == CODEC_TYPE_DIVX) {
7373 mp4StreamType psBits;
7374 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7375 psBits.numBytes = pdest_frame->nFilledLen;
7376 mp4_headerparser.parseHeader(&psBits);
7377 }
7378
7379 frame_count++;
7380 } else {
7381 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7382 if (pdest_frame->nFilledLen) {
7383 /*Push the frame to the Decoder*/
7384 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7385 return OMX_ErrorBadParameter;
7386 }
7387 frame_count++;
7388 pdest_frame = NULL;
7389
7390 if (m_input_free_q.m_size) {
7391 m_input_free_q.pop_entry(&address,&p2,&id);
7392 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7393 pdest_frame->nFilledLen = 0;
7394 }
7395 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007396 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007397 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7398 (unsigned)NULL);
7399 pdest_frame = NULL;
7400 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007401 }
Arun Menon906de572013-06-18 17:01:40 -07007402 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007403 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007404 /*Check if Destination Buffer is full*/
7405 if (pdest_frame->nAllocLen ==
7406 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007407 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007408 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007409 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007410 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007411
Arun Menon906de572013-06-18 17:01:40 -07007412 if (psource_frame->nFilledLen == 0) {
7413 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7414 if (pdest_frame) {
7415 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007416 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007417 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007418 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007419 pdest_frame->nFilledLen,frame_count++);
7420 /*Push the frame to the Decoder*/
7421 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7422 return OMX_ErrorBadParameter;
7423 }
7424 frame_count++;
7425 pdest_frame = NULL;
7426 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007427 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007428 generate_ebd = OMX_FALSE;
7429 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007430 }
Arun Menon906de572013-06-18 17:01:40 -07007431 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007432 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007433 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7434 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007435
Arun Menon906de572013-06-18 17:01:40 -07007436 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007437 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007438 m_input_pending_q.pop_entry(&address,&p2,&id);
7439 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007440 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007441 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007442 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007443 psource_frame->nFlags,psource_frame->nFilledLen);
7444 }
7445 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007446 }
Arun Menon906de572013-06-18 17:01:40 -07007447 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007448}
7449
7450OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7451{
Arun Menon906de572013-06-18 17:01:40 -07007452 OMX_U32 partial_frame = 1;
7453 unsigned address = 0, p2 = 0, id = 0;
7454 OMX_BOOL isNewFrame = OMX_FALSE;
7455 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007456
Arun Menon906de572013-06-18 17:01:40 -07007457 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007458 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007459 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007460 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007461 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007462 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007463 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007464 if (h264_scratch.nFilledLen && look_ahead_nal) {
7465 look_ahead_nal = false;
7466 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7467 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007468 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7469 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7470 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007471 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007472 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007473 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007474 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007475 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007476 }
Arun Menon906de572013-06-18 17:01:40 -07007477 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007478
7479 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7480 in EOS flag getting associated with the destination
7481 */
7482 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7483 pdest_frame->nFilledLen) {
7484 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7485 generate_ebd = OMX_FALSE;
7486 }
7487
Arun Menon906de572013-06-18 17:01:40 -07007488 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007489 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007490 if (m_frame_parser.parse_sc_frame(psource_frame,
7491 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007492 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007493 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007494 }
Arun Menon906de572013-06-18 17:01:40 -07007495 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007496 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007497 if (m_frame_parser.parse_h264_nallength(psource_frame,
7498 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007499 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007500 return OMX_ErrorBadParameter;
7501 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007502 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007503
Arun Menon906de572013-06-18 17:01:40 -07007504 if (partial_frame == 0) {
7505 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007506 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007507 nal_count++;
7508 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7509 h264_scratch.nFlags = psource_frame->nFlags;
7510 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007511 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007512 if (h264_scratch.nFilledLen) {
7513 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7514 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007515#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007516 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7517 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7518 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7519 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7520 // If timeinfo is present frame info from SEI is already processed
7521 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7522 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007523#endif
Arun Menon906de572013-06-18 17:01:40 -07007524 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7525 nal_count++;
7526 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7527 pdest_frame->nTimeStamp = h264_last_au_ts;
7528 pdest_frame->nFlags = h264_last_au_flags;
7529#ifdef PANSCAN_HDLR
7530 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7531 h264_parser->update_panscan_data(h264_last_au_ts);
7532#endif
7533 }
7534 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7535 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7536 h264_last_au_ts = h264_scratch.nTimeStamp;
7537 h264_last_au_flags = h264_scratch.nFlags;
7538#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7539 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7540 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7541 if (!VALID_TS(h264_last_au_ts))
7542 h264_last_au_ts = ts_in_sei;
7543 }
7544#endif
7545 } else
7546 h264_last_au_ts = LLONG_MAX;
7547 }
7548
7549 if (!isNewFrame) {
7550 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7551 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007552 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007553 h264_scratch.nFilledLen);
7554 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7555 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7556 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7557 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7558 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7559 h264_scratch.nFilledLen = 0;
7560 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007561 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007562 return OMX_ErrorBadParameter;
7563 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007564 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007565 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007566 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007567 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007568 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007569 pdest_frame->nFilledLen,frame_count++);
7570
7571 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007572 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007573 look_ahead_nal = false;
7574 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7575 h264_scratch.nFilledLen) {
7576 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7577 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7578 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7579 h264_scratch.nFilledLen = 0;
7580 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007581 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007582 return OMX_ErrorBadParameter;
7583 }
7584 } else {
7585 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007586 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007587 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7588 }
7589 /*Push the frame to the Decoder*/
7590 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7591 return OMX_ErrorBadParameter;
7592 }
7593 //frame_count++;
7594 pdest_frame = NULL;
7595 if (m_input_free_q.m_size) {
7596 m_input_free_q.pop_entry(&address,&p2,&id);
7597 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007598 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007599 pdest_frame->nFilledLen = 0;
7600 pdest_frame->nFlags = 0;
7601 pdest_frame->nTimeStamp = LLONG_MAX;
7602 }
7603 }
7604 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007605 }
Arun Menon906de572013-06-18 17:01:40 -07007606 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007607 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007608 /*Check if Destination Buffer is full*/
7609 if (h264_scratch.nAllocLen ==
7610 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007611 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007612 return OMX_ErrorStreamCorrupt;
7613 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007614 }
Arun Menon906de572013-06-18 17:01:40 -07007615
7616 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007617 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007618
7619 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7620 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007621 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007622 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7623 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007624 if(pdest_frame->nFilledLen == 0) {
7625 /* No residual frame from before, send whatever
7626 * we have left */
7627 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7628 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7629 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7630 h264_scratch.nFilledLen = 0;
7631 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7632 } else {
7633 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7634 if(!isNewFrame) {
7635 /* Have a residual frame, but we know that the
7636 * AU in this frame is belonging to whatever
7637 * frame we had left over. So append it */
7638 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7639 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7640 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7641 h264_scratch.nFilledLen = 0;
Balamurugan Alagarsamyefde3832014-09-22 19:52:20 +05307642 if (h264_last_au_ts != LLONG_MAX)
7643 pdest_frame->nTimeStamp = h264_last_au_ts;
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007644 } else {
7645 /* Completely new frame, let's just push what
7646 * we have now. The resulting EBD would trigger
7647 * another push */
7648 generate_ebd = OMX_FALSE;
7649 pdest_frame->nTimeStamp = h264_last_au_ts;
7650 h264_last_au_ts = h264_scratch.nTimeStamp;
7651 }
7652 }
Arun Menon906de572013-06-18 17:01:40 -07007653 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007654 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007655 return OMX_ErrorBadParameter;
7656 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007657
7658 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7659 if(generate_ebd == OMX_TRUE) {
7660 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7661 }
Arun Menon906de572013-06-18 17:01:40 -07007662
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007663 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007664 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007665 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007666#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7667 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7668 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7669 if (!VALID_TS(pdest_frame->nTimeStamp))
7670 pdest_frame->nTimeStamp = ts_in_sei;
7671 }
7672#endif
7673 /*Push the frame to the Decoder*/
7674 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7675 return OMX_ErrorBadParameter;
7676 }
7677 frame_count++;
7678 pdest_frame = NULL;
7679 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007680 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007681 pdest_frame,h264_scratch.nFilledLen);
7682 generate_ebd = OMX_FALSE;
7683 }
7684 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007685 }
Arun Menon906de572013-06-18 17:01:40 -07007686 if (generate_ebd && !psource_frame->nFilledLen) {
7687 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7688 psource_frame = NULL;
7689 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007690 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007691 m_input_pending_q.pop_entry(&address,&p2,&id);
7692 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007693 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007694 psource_frame->nFlags,psource_frame->nFilledLen);
7695 }
7696 }
7697 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007698}
7699
7700OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7701{
7702 OMX_U8 *buf, *pdest;
7703 OMX_U32 partial_frame = 1;
7704 OMX_U32 buf_len, dest_len;
7705
Arun Menon906de572013-06-18 17:01:40 -07007706 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007707 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007708 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007709 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007710 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007711 buf = psource_frame->pBuffer;
7712 buf_len = psource_frame->nFilledLen;
7713
7714 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007715 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007716 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007717 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007718 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007719 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007720 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007721 return OMX_ErrorStreamCorrupt;
7722 }
Arun Menon906de572013-06-18 17:01:40 -07007723 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007724 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7725 pdest_frame->nOffset;
7726 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007727 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007728
Arun Menon906de572013-06-18 17:01:40 -07007729 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007730 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007731 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007732 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007733 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7734 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7735 }
7736 }
7737 }
7738
Arun Menon906de572013-06-18 17:01:40 -07007739 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007740 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007741 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007742 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007743 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007744 return OMX_ErrorBadParameter;
7745 }
Arun Menon906de572013-06-18 17:01:40 -07007746 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007747
7748 case VC1_SP_MP_RCV:
7749 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007750 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007751 return OMX_ErrorBadParameter;
7752 }
7753 return OMX_ErrorNone;
7754}
7755
David Ng38e2d232013-03-15 20:05:58 -07007756#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007757bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007758 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007759{
Arun Menon906de572013-06-18 17:01:40 -07007760 struct pmem_allocation allocation;
7761 allocation.size = buffer_size;
7762 allocation.align = clip2(alignment);
7763 if (allocation.align < 4096) {
7764 allocation.align = 4096;
7765 }
7766 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007767 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007768 allocation.align, allocation.size);
7769 return false;
7770 }
7771 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007772}
David Ng38e2d232013-03-15 20:05:58 -07007773#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007774#ifdef USE_ION
7775int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007776 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7777 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007778{
Arun Menon906de572013-06-18 17:01:40 -07007779 int fd = -EINVAL;
7780 int rc = -EINVAL;
7781 int ion_dev_flag;
7782 struct vdec_ion ion_buf_info;
7783 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007784 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007785 return -EINVAL;
7786 }
7787 ion_dev_flag = O_RDONLY;
7788 fd = open (MEM_DEVICE, ion_dev_flag);
7789 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007790 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007791 return fd;
7792 }
7793 alloc_data->flags = 0;
7794 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7795 alloc_data->flags |= ION_FLAG_CACHED;
7796 }
7797 alloc_data->len = buffer_size;
7798 alloc_data->align = clip2(alignment);
7799 if (alloc_data->align < 4096) {
7800 alloc_data->align = 4096;
7801 }
7802 if ((secure_mode) && (flag & ION_SECURE))
7803 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007804
Arun Menon906de572013-06-18 17:01:40 -07007805 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307806 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007807 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7808 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7809 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007810 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007811 alloc_data->handle = NULL;
7812 close(fd);
7813 fd = -ENOMEM;
7814 return fd;
7815 }
7816 fd_data->handle = alloc_data->handle;
7817 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7818 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007819 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007820 ion_buf_info.ion_alloc_data = *alloc_data;
7821 ion_buf_info.ion_device_fd = fd;
7822 ion_buf_info.fd_ion_data = *fd_data;
7823 free_ion_memory(&ion_buf_info);
7824 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007825 fd = -ENOMEM;
7826 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007827
Arun Menon906de572013-06-18 17:01:40 -07007828 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007829}
7830
Arun Menon906de572013-06-18 17:01:40 -07007831void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7832{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007833
Arun Menon906de572013-06-18 17:01:40 -07007834 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007835 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007836 return;
7837 }
7838 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7839 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007840 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007841 }
7842 close(buf_ion_info->ion_device_fd);
7843 buf_ion_info->ion_device_fd = -1;
7844 buf_ion_info->ion_alloc_data.handle = NULL;
7845 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007846}
7847#endif
7848void omx_vdec::free_output_buffer_header()
7849{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007850 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007851 output_use_buffer = false;
7852 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007853
Arun Menon906de572013-06-18 17:01:40 -07007854 if (m_out_mem_ptr) {
7855 free (m_out_mem_ptr);
7856 m_out_mem_ptr = NULL;
7857 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007858
Arun Menon906de572013-06-18 17:01:40 -07007859 if (m_platform_list) {
7860 free(m_platform_list);
7861 m_platform_list = NULL;
7862 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007863
Arun Menon906de572013-06-18 17:01:40 -07007864 if (drv_ctx.ptr_respbuffer) {
7865 free (drv_ctx.ptr_respbuffer);
7866 drv_ctx.ptr_respbuffer = NULL;
7867 }
7868 if (drv_ctx.ptr_outputbuffer) {
7869 free (drv_ctx.ptr_outputbuffer);
7870 drv_ctx.ptr_outputbuffer = NULL;
7871 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007872#ifdef USE_ION
7873 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007874 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007875 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007876 drv_ctx.op_buf_ion_info = NULL;
7877 }
7878#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007879 if (out_dynamic_list) {
7880 free(out_dynamic_list);
7881 out_dynamic_list = NULL;
7882 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007883}
7884
7885void omx_vdec::free_input_buffer_header()
7886{
7887 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007888 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007889 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007890 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007891 free (m_inp_heap_ptr);
7892 m_inp_heap_ptr = NULL;
7893 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007894
Arun Menon906de572013-06-18 17:01:40 -07007895 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007896 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007897 free (m_phdr_pmem_ptr);
7898 m_phdr_pmem_ptr = NULL;
7899 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007900 }
Arun Menon906de572013-06-18 17:01:40 -07007901 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007902 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007903 free (m_inp_mem_ptr);
7904 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007905 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007906 /* We just freed all the buffer headers, every thing in m_input_free_q,
7907 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007908 while (m_input_free_q.m_size) {
7909 unsigned address, p2, id;
7910 m_input_free_q.pop_entry(&address, &p2, &id);
7911 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007912 while (m_input_pending_q.m_size) {
7913 unsigned address, p2, id;
7914 m_input_pending_q.pop_entry(&address, &p2, &id);
7915 }
7916 pdest_frame = NULL;
7917 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007918 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007919 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007920 free (drv_ctx.ptr_inputbuffer);
7921 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007922 }
7923#ifdef USE_ION
7924 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007925 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007926 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007927 drv_ctx.ip_buf_ion_info = NULL;
7928 }
7929#endif
7930}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007931
7932int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007933{
Arun Menon906de572013-06-18 17:01:40 -07007934 enum v4l2_buf_type btype;
7935 int rc = 0;
7936 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007937
Arun Menon906de572013-06-18 17:01:40 -07007938 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7939 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7940 v4l2_port = OUTPUT_PORT;
7941 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7942 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7943 v4l2_port = CAPTURE_PORT;
7944 } else if (port == OMX_ALL) {
7945 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7946 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007947
Arun Menon906de572013-06-18 17:01:40 -07007948 if (!rc_input)
7949 return rc_input;
7950 else
7951 return rc_output;
7952 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007953
Arun Menon906de572013-06-18 17:01:40 -07007954 if (!streaming[v4l2_port]) {
7955 // already streamed off, warn and move on
7956 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7957 " which is already streamed off", v4l2_port);
7958 return 0;
7959 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007960
Arun Menon906de572013-06-18 17:01:40 -07007961 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007962
Arun Menon906de572013-06-18 17:01:40 -07007963 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7964 if (rc) {
7965 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007966 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007967 } else {
7968 streaming[v4l2_port] = false;
7969 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007970
Arun Menon906de572013-06-18 17:01:40 -07007971 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007972}
7973
7974OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7975{
Arun Menon906de572013-06-18 17:01:40 -07007976 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7977 struct v4l2_requestbuffers bufreq;
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07007978 unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307979 unsigned int final_extra_data_size = 0;
Arun Menon906de572013-06-18 17:01:40 -07007980 struct v4l2_format fmt;
7981 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007982 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007983 buffer_prop->actualcount, buffer_prop->buffer_size);
7984 bufreq.memory = V4L2_MEMORY_USERPTR;
7985 bufreq.count = 1;
7986 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7987 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7988 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7989 fmt.fmt.pix_mp.pixelformat = output_capability;
7990 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7991 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7992 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7993 fmt.fmt.pix_mp.pixelformat = capture_capability;
7994 } else {
7995 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007996 }
Arun Menon906de572013-06-18 17:01:40 -07007997 if (eRet==OMX_ErrorNone) {
7998 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007999 }
Arun Menon906de572013-06-18 17:01:40 -07008000 if (ret) {
8001 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8002 /*TODO: How to handle this case */
8003 eRet = OMX_ErrorInsufficientResources;
8004 return eRet;
8005 } else {
8006 buffer_prop->actualcount = bufreq.count;
8007 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008008 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008009 }
Arun Menon906de572013-06-18 17:01:40 -07008010 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
8011 buffer_prop->actualcount, buffer_prop->buffer_size);
8012
8013 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8014 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
8015
8016 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8017
8018 update_resolution(fmt.fmt.pix_mp.width,
8019 fmt.fmt.pix_mp.height,
8020 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
8021 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
8022 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
8023 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008024 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07008025
8026 if (ret) {
8027 /*TODO: How to handle this case */
8028 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8029 eRet = OMX_ErrorInsufficientResources;
8030 } else {
8031 int extra_idx = 0;
8032
8033 eRet = is_video_session_supported();
8034 if (eRet)
8035 return eRet;
8036
8037 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
8038 buf_size = buffer_prop->buffer_size;
8039 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
8040 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
8041 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
8042 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008043 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07008044 return OMX_ErrorBadParameter;
8045 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008046
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07008047 default_extra_data_size = VENUS_EXTRADATA_SIZE(
8048 drv_ctx.video_resolution.frame_height,
8049 drv_ctx.video_resolution.frame_width);
8050 final_extra_data_size = extra_data_size > default_extra_data_size ?
8051 extra_data_size : default_extra_data_size;
8052
8053 final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
8054 (~(buffer_prop->alignment - 1));
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07008055
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308056 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07008057 drv_ctx.extradata_info.count = buffer_prop->actualcount;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308058 drv_ctx.extradata_info.buffer_size = final_extra_data_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308059 if (!secure_mode)
8060 buf_size += final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07008061 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8062 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
8063 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008064 if (extra_data_size)
8065 DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%d)",
8066 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
8067
Arun Menon906de572013-06-18 17:01:40 -07008068 if (in_reconfig) // BufReq will be set to driver when port is disabled
8069 buffer_prop->buffer_size = buf_size;
8070 else if (buf_size != buffer_prop->buffer_size) {
8071 buffer_prop->buffer_size = buf_size;
8072 eRet = set_buffer_req(buffer_prop);
8073 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008074 }
Arun Menon906de572013-06-18 17:01:40 -07008075 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
8076 buffer_prop->actualcount, buffer_prop->buffer_size);
8077 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008078}
8079
8080OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
8081{
Arun Menon906de572013-06-18 17:01:40 -07008082 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8083 unsigned buf_size = 0;
8084 struct v4l2_format fmt;
8085 struct v4l2_requestbuffers bufreq;
8086 int ret;
8087 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
8088 buffer_prop->actualcount, buffer_prop->buffer_size);
8089 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8090 if (buf_size != buffer_prop->buffer_size) {
8091 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
8092 buffer_prop->buffer_size, buf_size);
8093 eRet = OMX_ErrorBadParameter;
8094 } else {
8095 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8096 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008097
Arun Menon906de572013-06-18 17:01:40 -07008098 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8099 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8100 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07008101 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07008102 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8103 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8104 fmt.fmt.pix_mp.pixelformat = capture_capability;
8105 } else {
8106 eRet = OMX_ErrorBadParameter;
8107 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008108
Arun Menon906de572013-06-18 17:01:40 -07008109 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
8110 if (ret) {
8111 /*TODO: How to handle this case */
8112 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
8113 eRet = OMX_ErrorInsufficientResources;
8114 }
8115
8116 bufreq.memory = V4L2_MEMORY_USERPTR;
8117 bufreq.count = buffer_prop->actualcount;
8118 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8119 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8120 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8121 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8122 } else {
8123 eRet = OMX_ErrorBadParameter;
8124 }
8125
8126 if (eRet==OMX_ErrorNone) {
8127 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8128 }
8129
8130 if (ret) {
8131 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8132 /*TODO: How to handle this case */
8133 eRet = OMX_ErrorInsufficientResources;
8134 } else if (bufreq.count < buffer_prop->actualcount) {
8135 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8136 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8137 buffer_prop->actualcount, bufreq.count);
8138 eRet = OMX_ErrorInsufficientResources;
8139 } else {
8140 if (!client_buffers.update_buffer_req()) {
8141 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8142 eRet = OMX_ErrorInsufficientResources;
8143 }
8144 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008145 }
Arun Menon906de572013-06-18 17:01:40 -07008146 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008147}
8148
Shalaj Jain273b3e02012-06-22 19:08:03 -07008149OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8150{
Arun Menon906de572013-06-18 17:01:40 -07008151 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8152 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008153}
8154
8155OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8156{
Arun Menon906de572013-06-18 17:01:40 -07008157 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308158 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07008159 if (!portDefn) {
8160 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008161 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008162 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07008163 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8164 portDefn->nSize = sizeof(portDefn);
8165 portDefn->eDomain = OMX_PortDomainVideo;
8166 if (drv_ctx.frame_rate.fps_denominator > 0)
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08008167 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
8168 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
Arun Menon906de572013-06-18 17:01:40 -07008169 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008170 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07008171 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008172 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308173 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Arun Menon906de572013-06-18 17:01:40 -07008174 if (0 == portDefn->nPortIndex) {
8175 portDefn->eDir = OMX_DirInput;
8176 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8177 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8178 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8179 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8180 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8181 portDefn->bEnabled = m_inp_bEnabled;
8182 portDefn->bPopulated = m_inp_bPopulated;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308183
8184 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8185 fmt.fmt.pix_mp.pixelformat = output_capability;
Arun Menon906de572013-06-18 17:01:40 -07008186 } else if (1 == portDefn->nPortIndex) {
8187 unsigned int buf_size = 0;
8188 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008189 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07008190 return OMX_ErrorHardware;
8191 }
8192 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008193 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07008194 return OMX_ErrorHardware;
8195 }
8196 portDefn->nBufferSize = buf_size;
8197 portDefn->eDir = OMX_DirOutput;
8198 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8199 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
8200 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8201 portDefn->bEnabled = m_out_bEnabled;
8202 portDefn->bPopulated = m_out_bPopulated;
8203 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008204 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07008205 return OMX_ErrorHardware;
8206 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308207 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8208 fmt.fmt.pix_mp.pixelformat = capture_capability;
Arun Menon906de572013-06-18 17:01:40 -07008209 } else {
8210 portDefn->eDir = OMX_DirMax;
8211 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8212 (int)portDefn->nPortIndex);
8213 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008214 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308215 if (is_down_scalar_enabled) {
8216 int ret = 0;
8217 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8218 if (ret) {
8219 DEBUG_PRINT_ERROR("update_portdef : Error in getting port resolution");
8220 return OMX_ErrorHardware;
8221 } else {
8222 portDefn->format.video.nFrameWidth = fmt.fmt.pix_mp.width;
8223 portDefn->format.video.nFrameHeight = fmt.fmt.pix_mp.height;
8224 portDefn->format.video.nStride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
8225 portDefn->format.video.nSliceHeight = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
8226 }
8227 } else {
8228 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8229 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8230 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8231 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
8232 }
8233
Praveen Chavandb7776f2014-02-06 18:17:25 -08008234 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
8235 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308236 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
8237 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
8238 }
8239 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
8240 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
8241 portDefn->nPortIndex,
8242 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07008243 portDefn->format.video.nFrameHeight,
8244 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308245 portDefn->format.video.nSliceHeight,
8246 portDefn->format.video.eColorFormat,
8247 portDefn->nBufferSize,
8248 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008249
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308250 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008251}
8252
8253OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8254{
Arun Menon906de572013-06-18 17:01:40 -07008255 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8256 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8257 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008258
Arun Menon906de572013-06-18 17:01:40 -07008259 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008260 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07008261 int nBufHdrSize = 0;
8262 int nPlatformEntrySize = 0;
8263 int nPlatformListSize = 0;
8264 int nPMEMInfoSize = 0;
8265 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8266 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8267 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008268
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008269 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008270 drv_ctx.op_buf.actualcount);
8271 nBufHdrSize = drv_ctx.op_buf.actualcount *
8272 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008273
Arun Menon906de572013-06-18 17:01:40 -07008274 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8275 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8276 nPlatformListSize = drv_ctx.op_buf.actualcount *
8277 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8278 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8279 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008280
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008281 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07008282 sizeof(OMX_BUFFERHEADERTYPE),
8283 nPMEMInfoSize,
8284 nPlatformListSize);
Deva Ramasubramanianeb819322014-07-17 14:23:35 -07008285 DEBUG_PRINT_LOW("PE %d bmSize %"PRId64, nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07008286 m_out_bm_count);
8287 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8288 // Alloc mem for platform specific info
8289 char *pPtr=NULL;
8290 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8291 nPMEMInfoSize,1);
8292 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8293 calloc (sizeof(struct vdec_bufferpayload),
8294 drv_ctx.op_buf.actualcount);
8295 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8296 calloc (sizeof (struct vdec_output_frameinfo),
8297 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008298 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
8299 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
8300 return OMX_ErrorInsufficientResources;
8301 }
8302
Shalaj Jain273b3e02012-06-22 19:08:03 -07008303#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008304 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8305 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008306 if (!drv_ctx.op_buf_ion_info) {
8307 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
8308 return OMX_ErrorInsufficientResources;
8309 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008310#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07008311 if (dynamic_buf_mode) {
8312 out_dynamic_list = (struct dynamic_buf_list *) \
8313 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
8314 }
Arun Menon906de572013-06-18 17:01:40 -07008315 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8316 && drv_ctx.ptr_respbuffer) {
8317 bufHdr = m_out_mem_ptr;
8318 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8319 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8320 (((char *) m_platform_list) + nPlatformListSize);
8321 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8322 (((char *) m_platform_entry) + nPlatformEntrySize);
8323 pPlatformList = m_platform_list;
8324 pPlatformEntry = m_platform_entry;
8325 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008326
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008327 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008328
Arun Menon906de572013-06-18 17:01:40 -07008329 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008330 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07008331 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008332 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07008333 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
8334 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8335 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8336 // Set the values when we determine the right HxW param
8337 bufHdr->nAllocLen = 0;
8338 bufHdr->nFilledLen = 0;
8339 bufHdr->pAppPrivate = NULL;
8340 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8341 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8342 pPlatformEntry->entry = pPMEMInfo;
8343 // Initialize the Platform List
8344 pPlatformList->nEntries = 1;
8345 pPlatformList->entryList = pPlatformEntry;
8346 // Keep pBuffer NULL till vdec is opened
8347 bufHdr->pBuffer = NULL;
8348 pPMEMInfo->offset = 0;
8349 pPMEMInfo->pmem_fd = 0;
8350 bufHdr->pPlatformPrivate = pPlatformList;
8351 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008352#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008353 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008354#endif
Arun Menon906de572013-06-18 17:01:40 -07008355 /*Create a mapping between buffers*/
8356 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8357 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8358 &drv_ctx.ptr_outputbuffer[i];
8359 // Move the buffer and buffer header pointers
8360 bufHdr++;
8361 pPMEMInfo++;
8362 pPlatformEntry++;
8363 pPlatformList++;
8364 }
8365 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008366 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008367 m_out_mem_ptr, pPtr);
8368 if (m_out_mem_ptr) {
8369 free(m_out_mem_ptr);
8370 m_out_mem_ptr = NULL;
8371 }
8372 if (pPtr) {
8373 free(pPtr);
8374 pPtr = NULL;
8375 }
8376 if (drv_ctx.ptr_outputbuffer) {
8377 free(drv_ctx.ptr_outputbuffer);
8378 drv_ctx.ptr_outputbuffer = NULL;
8379 }
8380 if (drv_ctx.ptr_respbuffer) {
8381 free(drv_ctx.ptr_respbuffer);
8382 drv_ctx.ptr_respbuffer = NULL;
8383 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008384#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008385 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008386 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008387 free(drv_ctx.op_buf_ion_info);
8388 drv_ctx.op_buf_ion_info = NULL;
8389 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008390#endif
Arun Menon906de572013-06-18 17:01:40 -07008391 eRet = OMX_ErrorInsufficientResources;
8392 }
8393 } else {
8394 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008395 }
Arun Menon906de572013-06-18 17:01:40 -07008396 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008397}
8398
8399void omx_vdec::complete_pending_buffer_done_cbs()
8400{
Arun Menon906de572013-06-18 17:01:40 -07008401 unsigned p1;
8402 unsigned p2;
8403 unsigned ident;
8404 omx_cmd_queue tmp_q, pending_bd_q;
8405 pthread_mutex_lock(&m_lock);
8406 // pop all pending GENERATE FDB from ftb queue
8407 while (m_ftb_q.m_size) {
8408 m_ftb_q.pop_entry(&p1,&p2,&ident);
8409 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8410 pending_bd_q.insert_entry(p1,p2,ident);
8411 } else {
8412 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008413 }
Arun Menon906de572013-06-18 17:01:40 -07008414 }
8415 //return all non GENERATE FDB to ftb queue
8416 while (tmp_q.m_size) {
8417 tmp_q.pop_entry(&p1,&p2,&ident);
8418 m_ftb_q.insert_entry(p1,p2,ident);
8419 }
8420 // pop all pending GENERATE EDB from etb queue
8421 while (m_etb_q.m_size) {
8422 m_etb_q.pop_entry(&p1,&p2,&ident);
8423 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8424 pending_bd_q.insert_entry(p1,p2,ident);
8425 } else {
8426 tmp_q.insert_entry(p1,p2,ident);
8427 }
8428 }
8429 //return all non GENERATE FDB to etb queue
8430 while (tmp_q.m_size) {
8431 tmp_q.pop_entry(&p1,&p2,&ident);
8432 m_etb_q.insert_entry(p1,p2,ident);
8433 }
8434 pthread_mutex_unlock(&m_lock);
8435 // process all pending buffer dones
8436 while (pending_bd_q.m_size) {
8437 pending_bd_q.pop_entry(&p1,&p2,&ident);
8438 switch (ident) {
8439 case OMX_COMPONENT_GENERATE_EBD:
8440 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008441 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008442 omx_report_error ();
8443 }
8444 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008445
Arun Menon906de572013-06-18 17:01:40 -07008446 case OMX_COMPONENT_GENERATE_FBD:
8447 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008448 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008449 omx_report_error ();
8450 }
8451 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008452 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008453 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008454}
8455
8456void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8457{
Arun Menon906de572013-06-18 17:01:40 -07008458 OMX_U32 new_frame_interval = 0;
8459 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8460 && llabs(act_timestamp - prev_ts) > 2000) {
8461 new_frame_interval = client_set_fps ? frm_int :
8462 llabs(act_timestamp - prev_ts);
Arun Menond9e49f82014-04-23 18:50:26 -07008463 if (new_frame_interval != frm_int || frm_int == 0) {
Arun Menon906de572013-06-18 17:01:40 -07008464 frm_int = new_frame_interval;
8465 if (frm_int) {
8466 drv_ctx.frame_rate.fps_numerator = 1e6;
8467 drv_ctx.frame_rate.fps_denominator = frm_int;
8468 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8469 frm_int, drv_ctx.frame_rate.fps_numerator /
8470 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008471
Arun Menon906de572013-06-18 17:01:40 -07008472 /* We need to report the difference between this FBD and the previous FBD
8473 * back to the driver for clock scaling purposes. */
8474 struct v4l2_outputparm oparm;
8475 /*XXX: we're providing timing info as seconds per frame rather than frames
8476 * per second.*/
8477 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8478 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008479
Arun Menon906de572013-06-18 17:01:40 -07008480 struct v4l2_streamparm sparm;
8481 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8482 sparm.parm.output = oparm;
8483 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8484 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8485 performance might be affected");
8486 }
8487
8488 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008489 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008490 }
Arun Menon906de572013-06-18 17:01:40 -07008491 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008492}
8493
8494void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8495{
Arun Menon906de572013-06-18 17:01:40 -07008496 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8497 prev_ts = act_timestamp;
8498 rst_prev_ts = false;
8499 } else if (VALID_TS(prev_ts)) {
8500 bool codec_cond = (drv_ctx.timestamp_adjust)?
Deva Ramasubramanian5f3cff32014-12-04 17:13:01 -08008501 (!VALID_TS(act_timestamp) || act_timestamp < prev_ts || llabs(act_timestamp - prev_ts) <= 2000) :
8502 (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts);
Arun Menon906de572013-06-18 17:01:40 -07008503 if (frm_int > 0 && codec_cond) {
8504 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8505 act_timestamp = prev_ts + frm_int;
8506 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8507 prev_ts = act_timestamp;
Leena Winterrowdd139fdc2014-08-05 18:04:25 -07008508 } else {
8509 if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
8510 // ensure that timestamps can never step backwards when in display order
8511 act_timestamp = prev_ts;
8512 }
Arun Menon906de572013-06-18 17:01:40 -07008513 set_frame_rate(act_timestamp);
Leena Winterrowdd139fdc2014-08-05 18:04:25 -07008514 }
Arun Menon906de572013-06-18 17:01:40 -07008515 } else if (frm_int > 0) // In this case the frame rate was set along
8516 { // with the port definition, start ts with 0
8517 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8518 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008519 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008520}
8521
8522void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8523{
Arun Menon906de572013-06-18 17:01:40 -07008524 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8525 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308526 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008527 OMX_U32 frame_rate = 0;
8528 int consumed_len = 0;
8529 OMX_U32 num_MB_in_frame;
8530 OMX_U32 recovery_sei_flags = 1;
8531 int enable = 0;
Arun Menon7b6fd642014-02-13 16:48:36 -08008532
Arun Menon906de572013-06-18 17:01:40 -07008533 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008534 if (buf_index >= drv_ctx.extradata_info.count) {
8535 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8536 buf_index, drv_ctx.extradata_info.count);
8537 return;
8538 }
Arun Menon906de572013-06-18 17:01:40 -07008539 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8540 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8541 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308542
Arun Menon906de572013-06-18 17:01:40 -07008543 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308544 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008545 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008546 }
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308547
8548 if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
8549 DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
8550 p_extra = NULL;
8551 return;
8552 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308553 if (!secure_mode)
8554 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008555 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308556 else
8557 p_extra = m_other_extradata;
8558
Arun Menon906de572013-06-18 17:01:40 -07008559 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308560 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
8561 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
Arun Menon906de572013-06-18 17:01:40 -07008562 p_extra = NULL;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308563 return;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008564 }
Arun Menon906de572013-06-18 17:01:40 -07008565 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008566 if (data && p_extra) {
Arun Menon906de572013-06-18 17:01:40 -07008567 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8568 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308569 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008570 DEBUG_PRINT_LOW("Invalid extra data size");
8571 break;
8572 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308573 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008574 switch ((unsigned long)data->eType) {
8575 case EXTRADATA_INTERLACE_VIDEO:
8576 struct msm_vidc_interlace_payload *payload;
8577 payload = (struct msm_vidc_interlace_payload *)data->data;
Arun Menon7b6fd642014-02-13 16:48:36 -08008578 if (payload) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008579 enable = 1;
Arun Menon7b6fd642014-02-13 16:48:36 -08008580 switch (payload->format) {
8581 case INTERLACE_FRAME_PROGRESSIVE:
8582 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8583 enable = 0;
8584 break;
8585 case INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
8586 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8587 break;
8588 case INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
8589 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
8590 break;
8591 default:
8592 DEBUG_PRINT_LOW("default case - set interlace to topfield");
8593 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8594 }
Arun Menon906de572013-06-18 17:01:40 -07008595 }
8596 if (m_enable_android_native_buffers)
8597 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8598 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308599 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon7b6fd642014-02-13 16:48:36 -08008600 append_interlace_extradata(p_extra, payload->format,
8601 p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
Arun Menon906de572013-06-18 17:01:40 -07008602 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8603 }
8604 break;
8605 case EXTRADATA_FRAME_RATE:
8606 struct msm_vidc_framerate_payload *frame_rate_payload;
8607 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8608 frame_rate = frame_rate_payload->frame_rate;
8609 break;
8610 case EXTRADATA_TIMESTAMP:
8611 struct msm_vidc_ts_payload *time_stamp_payload;
8612 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308613 time_stamp = time_stamp_payload->timestamp_lo;
8614 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8615 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008616 break;
8617 case EXTRADATA_NUM_CONCEALED_MB:
8618 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8619 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8620 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8621 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8622 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8623 break;
8624 case EXTRADATA_INDEX:
8625 int *etype;
8626 etype = (int *)(data->data);
8627 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8628 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8629 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8630 if (aspect_ratio_payload) {
8631 ((struct vdec_output_frameinfo *)
8632 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8633 ((struct vdec_output_frameinfo *)
8634 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8635 }
8636 }
8637 break;
8638 case EXTRADATA_RECOVERY_POINT_SEI:
8639 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8640 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8641 recovery_sei_flags = recovery_sei_payload->flags;
8642 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8643 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008644 DEBUG_PRINT_HIGH("");
8645 DEBUG_PRINT_HIGH("***************************************************");
8646 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8647 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008648 }
8649 break;
8650 case EXTRADATA_PANSCAN_WINDOW:
8651 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8652 break;
8653 case EXTRADATA_MPEG2_SEQDISP:
8654 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8655 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8656 if (seqdisp_payload) {
8657 m_disp_hor_size = seqdisp_payload->disp_width;
8658 m_disp_vert_size = seqdisp_payload->disp_height;
8659 }
8660 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308661 case EXTRADATA_S3D_FRAME_PACKING:
8662 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8663 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308664 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308665 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8666 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8667 }
8668 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008669 case EXTRADATA_FRAME_QP:
8670 struct msm_vidc_frame_qp_payload *qp_payload;
8671 qp_payload = (struct msm_vidc_frame_qp_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308672 if (client_extradata & OMX_QP_EXTRADATA) {
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008673 append_qp_extradata(p_extra, qp_payload);
8674 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8675 }
8676 break;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008677 case EXTRADATA_FRAME_BITS_INFO:
8678 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
8679 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308680 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008681 append_bitsinfo_extradata(p_extra, bits_info_payload);
8682 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8683 }
8684 break;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008685 case EXTRADATA_STREAM_USERDATA:
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308686 if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008687 append_user_extradata(p_extra, data);
8688 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8689 }
8690 break;
Arun Menon906de572013-06-18 17:01:40 -07008691 default:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008692 DEBUG_PRINT_LOW("Unrecognized extradata");
Arun Menon906de572013-06-18 17:01:40 -07008693 goto unrecognized_extradata;
8694 }
8695 consumed_len += data->nSize;
8696 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8697 }
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308698 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008699 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8700 append_frame_info_extradata(p_extra,
8701 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308702 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008703 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008704 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008705 }
8706 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008707unrecognized_extradata:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008708 if (client_extradata && p_extra) {
8709 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Arun Menon906de572013-06-18 17:01:40 -07008710 append_terminator_extradata(p_extra);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008711 }
8712
Arun Menonfd723932014-05-30 17:56:31 -07008713 if (secure_mode && p_extradata && m_other_extradata) {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308714 struct vdec_output_frameinfo *ptr_extradatabuff = NULL;
8715 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
8716 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
8717 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
8718 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
8719 }
Arun Menon906de572013-06-18 17:01:40 -07008720 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008721}
8722
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008723OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008724 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008725{
Arun Menon906de572013-06-18 17:01:40 -07008726 OMX_ERRORTYPE ret = OMX_ErrorNone;
8727 struct v4l2_control control;
8728 if (m_state != OMX_StateLoaded) {
8729 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8730 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008731 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008732 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008733 client_extradata, requested_extradata, enable, is_internal);
8734
8735 if (!is_internal) {
8736 if (enable)
8737 client_extradata |= requested_extradata;
8738 else
8739 client_extradata = client_extradata & ~requested_extradata;
8740 }
8741
8742 if (enable) {
8743 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8744 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8745 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8746 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8747 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008748 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008749 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308750 }
8751 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008752 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8753 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8754 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008755 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008756 }
8757 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8758 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8759 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008760 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008761 }
8762 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8763 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8764 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008765 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008766 }
8767 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8768 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8769 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008770 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008771 }
8772 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8773 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8774 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008775 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008776 }
8777 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8778 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8779 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8780 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008781 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008782 }
8783 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308784 }
8785 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008786 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8787 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8788 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008789 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008790 }
8791 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308792 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8793 if (output_capability == V4L2_PIX_FMT_H264) {
8794 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8795 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8796 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8797 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8798 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8799 }
8800 } else {
8801 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8802 }
8803 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008804 if (requested_extradata & OMX_QP_EXTRADATA) {
8805 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8806 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
8807 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8808 DEBUG_PRINT_HIGH("Failed to set QP extradata");
8809 }
8810 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008811 if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
8812 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8813 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
8814 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8815 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
8816 }
8817 }
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008818 if (requested_extradata & OMX_EXTNUSER_EXTRADATA) {
8819 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8820 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
8821 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8822 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
8823 }
8824 }
Arun Menon906de572013-06-18 17:01:40 -07008825 }
8826 ret = get_buffer_req(&drv_ctx.op_buf);
8827 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008828}
8829
8830OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8831{
Arun Menon906de572013-06-18 17:01:40 -07008832 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8833 OMX_U8 *data_ptr = extra->data, data = 0;
8834 while (byte_count < extra->nDataSize) {
8835 data = *data_ptr;
8836 while (data) {
8837 num_MB += (data&0x01);
8838 data >>= 1;
8839 }
8840 data_ptr++;
8841 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008842 }
Arun Menon906de572013-06-18 17:01:40 -07008843 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8844 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8845 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008846}
8847
8848void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8849{
Arun Menon906de572013-06-18 17:01:40 -07008850 if (!m_debug_extradata)
8851 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008852
8853 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308854 "============== Extra Data ==============\n"
8855 " Size: %lu\n"
8856 " Version: %lu\n"
8857 " PortIndex: %lu\n"
8858 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008859 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008860 extra->nSize, extra->nVersion.nVersion,
8861 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008862
Arun Menon906de572013-06-18 17:01:40 -07008863 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8864 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8865 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308866 "------ Interlace Format ------\n"
8867 " Size: %lu\n"
8868 " Version: %lu\n"
8869 " PortIndex: %lu\n"
8870 " Is Interlace Format: %d\n"
8871 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008872 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008873 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8874 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8875 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8876 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8877
8878 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308879 "-------- Frame Format --------\n"
8880 " Picture Type: %d\n"
8881 " Interlace Type: %d\n"
8882 " Pan Scan Total Frame Num: %lu\n"
8883 " Concealed Macro Blocks: %lu\n"
8884 " frame rate: %lu\n"
8885 " Time Stamp: %llu\n"
8886 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008887 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008888 fminfo->ePicType,
8889 fminfo->interlaceType,
8890 fminfo->panScan.numWindows,
8891 fminfo->nConcealedMacroblocks,
8892 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308893 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008894 fminfo->aspectRatio.aspectRatioX,
8895 fminfo->aspectRatio.aspectRatioY);
8896
8897 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8898 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008899 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308900 " Pan Scan Frame Num: %lu\n"
8901 " Rectangle x: %ld\n"
8902 " Rectangle y: %ld\n"
8903 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008904 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008905 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8906 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8907 }
8908
8909 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308910 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8911 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8912 DEBUG_PRINT_HIGH(
8913 "------------------ Framepack Format ----------\n"
8914 " id: %lu \n"
8915 " cancel_flag: %lu \n"
8916 " type: %lu \n"
8917 " quincunx_sampling_flagFormat: %lu \n"
8918 " content_interpretation_type: %lu \n"
8919 " content_interpretation_type: %lu \n"
8920 " spatial_flipping_flag: %lu \n"
8921 " frame0_flipped_flag: %lu \n"
8922 " field_views_flag: %lu \n"
8923 " current_frame_is_frame0_flag: %lu \n"
8924 " frame0_self_contained_flag: %lu \n"
8925 " frame1_self_contained_flag: %lu \n"
8926 " frame0_grid_position_x: %lu \n"
8927 " frame0_grid_position_y: %lu \n"
8928 " frame1_grid_position_x: %lu \n"
8929 " frame1_grid_position_y: %lu \n"
8930 " reserved_byte: %lu \n"
8931 " repetition_period: %lu \n"
8932 " extension_flag: %lu \n"
8933 "================== End of Framepack ===========",
8934 framepack->id,
8935 framepack->cancel_flag,
8936 framepack->type,
8937 framepack->quincunx_sampling_flag,
8938 framepack->content_interpretation_type,
8939 framepack->spatial_flipping_flag,
8940 framepack->frame0_flipped_flag,
8941 framepack->field_views_flag,
8942 framepack->current_frame_is_frame0_flag,
8943 framepack->frame0_self_contained_flag,
8944 framepack->frame1_self_contained_flag,
8945 framepack->frame0_grid_position_x,
8946 framepack->frame0_grid_position_y,
8947 framepack->frame1_grid_position_x,
8948 framepack->frame1_grid_position_y,
8949 framepack->reserved_byte,
8950 framepack->repetition_period,
8951 framepack->extension_flag);
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008952 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
8953 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8954 DEBUG_PRINT_HIGH(
8955 "---- QP (Frame quantization parameter) ----\n"
8956 " Frame QP: %lu \n"
8957 "================ End of QP ================\n",
8958 qp->nQP);
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008959 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
8960 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)extra->data;
8961 DEBUG_PRINT_HIGH(
8962 "--------- Input bits information --------\n"
8963 " Header bits: %lu \n"
8964 " Frame bits: %lu \n"
8965 "===== End of Input bits information =====\n",
8966 bits->header_bits, bits->frame_bits);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008967 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
8968 OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)extra->data;
8969 OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
8970 OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
8971 OMX_U32 i = 0;
8972 DEBUG_PRINT_HIGH(
8973 "-------------- Userdata -------------\n"
8974 " Stream userdata type: %d\n"
8975 " userdata size: %d\n"
8976 " STREAM_USERDATA:",
8977 userdata->type, userdata_size);
8978 for (i = 0; i < userdata_size; i+=4) {
8979 DEBUG_PRINT_HIGH(" %x %x %x %x",
8980 data_ptr[i], data_ptr[i+1],
8981 data_ptr[i+2], data_ptr[i+3]);
8982 }
8983 DEBUG_PRINT_HIGH(
8984 "=========== End of Userdata ===========");
Arun Menon906de572013-06-18 17:01:40 -07008985 } else if (extra->eType == OMX_ExtraDataNone) {
8986 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8987 } else {
8988 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008989 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008990}
8991
8992void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon7b6fd642014-02-13 16:48:36 -08008993 OMX_U32 interlaced_format_type, bool is_mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008994{
Arun Menon906de572013-06-18 17:01:40 -07008995 OMX_STREAMINTERLACEFORMAT *interlace_format;
Arun Menon7b6fd642014-02-13 16:48:36 -08008996
Arun Menon906de572013-06-18 17:01:40 -07008997 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8998 return;
8999 }
9000 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
9001 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9002 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9003 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
9004 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9005 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
9006 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9007 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
9008 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
Arun Menon7b6fd642014-02-13 16:48:36 -08009009
9010 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
Arun Menon906de572013-06-18 17:01:40 -07009011 interlace_format->bInterlaceFormat = OMX_FALSE;
9012 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
9013 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08009014 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009015 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08009016 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009017 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08009018 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009019 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08009020 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009021 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07009022 } else {
9023 interlace_format->bInterlaceFormat = OMX_TRUE;
9024 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
9025 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
9026 }
9027 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009028}
9029
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009030void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07009031 struct vdec_aspectratioinfo *aspect_ratio_info,
9032 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009033{
Arun Menon906de572013-06-18 17:01:40 -07009034 m_extradata = frame_info;
9035 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
9036 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309037 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07009038 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009039}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009040
9041void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07009042 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309043 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009044 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009045{
Arun Menon906de572013-06-18 17:01:40 -07009046 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
9047 struct msm_vidc_panscan_window *panscan_window;
9048 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009049 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009050 }
Arun Menon906de572013-06-18 17:01:40 -07009051 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
9052 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9053 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9054 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
9055 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
9056 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
9057 switch (picture_type) {
9058 case PICTURE_TYPE_I:
9059 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
9060 break;
9061 case PICTURE_TYPE_P:
9062 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
9063 break;
9064 case PICTURE_TYPE_B:
9065 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
9066 break;
9067 default:
9068 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
9069 }
9070 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
9071 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
9072 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
9073 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
9074 else
9075 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
9076 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
9077 frame_info->nConcealedMacroblocks = num_conceal_mb;
9078 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309079 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07009080 frame_info->panScan.numWindows = 0;
9081 if (output_capability == V4L2_PIX_FMT_MPEG2) {
9082 if (m_disp_hor_size && m_disp_vert_size) {
9083 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
9084 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
Pushkaraj Patil5e6ebd92014-03-10 10:29:14 +05309085 } else {
9086 frame_info->displayAspectRatio.displayHorizontalSize = 0;
9087 frame_info->displayAspectRatio.displayVerticalSize = 0;
Arun Menon906de572013-06-18 17:01:40 -07009088 }
9089 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009090
Arun Menon906de572013-06-18 17:01:40 -07009091 if (panscan_payload) {
9092 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
9093 panscan_window = &panscan_payload->wnd[0];
9094 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
9095 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
9096 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
9097 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
9098 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
9099 panscan_window++;
9100 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009101 }
Arun Menon906de572013-06-18 17:01:40 -07009102 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
9103 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009104}
9105
9106void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9107{
Arun Menon906de572013-06-18 17:01:40 -07009108 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
9109 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
9110 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9111 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9112 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
9113 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
9114 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
9115 *portDefn = m_port_def;
9116 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009117 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07009118 portDefn->format.video.nFrameWidth,
9119 portDefn->format.video.nStride,
9120 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009121}
9122
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05309123void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9124 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
9125{
9126 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
9127 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
9128 DEBUG_PRINT_ERROR("frame packing size mismatch");
9129 return;
9130 }
9131 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
9132 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9133 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9134 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
9135 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9136 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
9137 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9138 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
9139 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9140 memcpy(&framepack->id, s3d_frame_packing_payload,
9141 sizeof(struct msm_vidc_s3d_frame_packing_payload));
9142 memcpy(&m_frame_pack_arrangement, framepack,
9143 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
9144 print_debug_extradata(extra);
9145}
9146
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08009147void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9148 struct msm_vidc_frame_qp_payload *qp_payload)
9149{
9150 OMX_QCOM_EXTRADATA_QP * qp = NULL;
9151 if (!qp_payload) {
9152 DEBUG_PRINT_ERROR("QP payload is NULL");
9153 return;
9154 }
9155 extra->nSize = OMX_QP_EXTRADATA_SIZE;
9156 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9157 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9158 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
9159 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
9160 qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
9161 qp->nQP = qp_payload->frame_qp;
9162 print_debug_extradata(extra);
9163}
9164
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08009165void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9166 struct msm_vidc_frame_bits_info_payload *bits_payload)
9167{
9168 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
9169 if (!bits_payload) {
9170 DEBUG_PRINT_ERROR("bits info payload is NULL");
9171 return;
9172 }
9173 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
9174 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9175 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9176 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
9177 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
9178 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)extra->data;
9179 bits->frame_bits = bits_payload->frame_bits;
9180 bits->header_bits = bits_payload->header_bits;
9181 print_debug_extradata(extra);
9182}
9183
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009184void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9185 OMX_OTHER_EXTRADATATYPE *p_user)
9186{
9187 int userdata_size = 0;
9188 struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
9189 userdata_payload =
9190 (struct msm_vidc_stream_userdata_payload *)p_user->data;
9191 userdata_size = p_user->nDataSize;
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07009192 extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + p_user->nSize;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009193 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9194 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9195 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
9196 extra->nDataSize = userdata_size;
9197 if (extra->data && p_user->data && extra->nDataSize)
9198 memcpy(extra->data, p_user->data, extra->nDataSize);
9199 print_debug_extradata(extra);
9200}
9201
Shalaj Jain273b3e02012-06-22 19:08:03 -07009202void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9203{
Arun Menon906de572013-06-18 17:01:40 -07009204 if (!client_extradata) {
9205 return;
9206 }
9207 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
9208 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9209 extra->eType = OMX_ExtraDataNone;
9210 extra->nDataSize = 0;
9211 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009212
Arun Menon906de572013-06-18 17:01:40 -07009213 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009214}
9215
9216OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
9217{
Arun Menon906de572013-06-18 17:01:40 -07009218 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9219 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009220 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07009221 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009222 }
Arun Menon906de572013-06-18 17:01:40 -07009223 if (m_desc_buffer_ptr == NULL) {
9224 m_desc_buffer_ptr = (desc_buffer_hdr*) \
9225 calloc( (sizeof(desc_buffer_hdr)),
9226 drv_ctx.ip_buf.actualcount);
9227 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009228 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009229 return OMX_ErrorInsufficientResources;
9230 }
9231 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009232
Arun Menon906de572013-06-18 17:01:40 -07009233 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
9234 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009235 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009236 return OMX_ErrorInsufficientResources;
9237 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009238
Arun Menon906de572013-06-18 17:01:40 -07009239 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009240}
9241
9242void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
9243{
Arun Menon906de572013-06-18 17:01:40 -07009244 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
9245 if (m_demux_entries < 8192) {
9246 m_demux_offsets[m_demux_entries++] = address_offset;
9247 }
9248 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009249}
9250
9251void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
9252{
Arun Menon906de572013-06-18 17:01:40 -07009253 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
9254 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
9255 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009256
Arun Menon906de572013-06-18 17:01:40 -07009257 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009258
Arun Menon906de572013-06-18 17:01:40 -07009259 while (index < bytes_to_parse) {
9260 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9261 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
9262 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9263 (buf[index+2] == 0x01)) ) {
9264 //Found start code, insert address offset
9265 insert_demux_addr_offset(index);
9266 if (buf[index+2] == 0x01) // 3 byte start code
9267 index += 3;
9268 else //4 byte start code
9269 index += 4;
9270 } else
9271 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009272 }
Arun Menon906de572013-06-18 17:01:40 -07009273 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
9274 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009275}
9276
9277OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
9278{
Arun Menon906de572013-06-18 17:01:40 -07009279 //fix this, handle 3 byte start code, vc1 terminator entry
9280 OMX_U8 *p_demux_data = NULL;
9281 OMX_U32 desc_data = 0;
9282 OMX_U32 start_addr = 0;
9283 OMX_U32 nal_size = 0;
9284 OMX_U32 suffix_byte = 0;
9285 OMX_U32 demux_index = 0;
9286 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009287
Arun Menon906de572013-06-18 17:01:40 -07009288 if (m_desc_buffer_ptr == NULL) {
9289 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
9290 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009291 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009292
Arun Menon906de572013-06-18 17:01:40 -07009293 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
9294 if (buffer_index > drv_ctx.ip_buf.actualcount) {
9295 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
9296 return OMX_ErrorBadParameter;
9297 }
9298
9299 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9300
9301 if ( ((OMX_U8*)p_demux_data == NULL) ||
9302 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
9303 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9304 return OMX_ErrorBadParameter;
9305 } else {
9306 for (; demux_index < m_demux_entries; demux_index++) {
9307 desc_data = 0;
9308 start_addr = m_demux_offsets[demux_index];
9309 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
9310 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9311 } else {
9312 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9313 }
9314 if (demux_index < (m_demux_entries - 1)) {
9315 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9316 } else {
9317 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9318 }
9319 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9320 (void *)start_addr,
9321 suffix_byte,
9322 nal_size,
9323 demux_index);
9324 desc_data = (start_addr >> 3) << 1;
9325 desc_data |= (start_addr & 7) << 21;
9326 desc_data |= suffix_byte << 24;
9327
9328 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9329 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9330 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9331 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9332
9333 p_demux_data += 16;
9334 }
9335 if (codec_type_parse == CODEC_TYPE_VC1) {
9336 DEBUG_PRINT_LOW("VC1 terminator entry");
9337 desc_data = 0;
9338 desc_data = 0x82 << 24;
9339 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9340 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9341 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9342 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9343 p_demux_data += 16;
9344 m_demux_entries++;
9345 }
9346 //Add zero word to indicate end of descriptors
9347 memset(p_demux_data, 0, sizeof(OMX_U32));
9348
9349 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
9350 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
9351 }
9352 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9353 m_demux_entries = 0;
9354 DEBUG_PRINT_LOW("Demux table complete!");
9355 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009356}
9357
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009358OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009359{
Arun Menon906de572013-06-18 17:01:40 -07009360 OMX_ERRORTYPE err = OMX_ErrorNone;
9361 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9362 if (iDivXDrmDecrypt) {
9363 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9364 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009365 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009366 delete iDivXDrmDecrypt;
9367 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07009368 }
9369 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009370 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07009371 err = OMX_ErrorUndefined;
9372 }
9373 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009374}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009375
Vinay Kaliada4f4422013-01-09 10:45:03 -08009376omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9377{
Arun Menon906de572013-06-18 17:01:40 -07009378 enabled = false;
9379 omx = NULL;
9380 init_members();
9381 ColorFormat = OMX_COLOR_FormatMax;
Praveen Chavandb7776f2014-02-06 18:17:25 -08009382 dest_format = YCbCr420P;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009383}
9384
9385void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9386{
Arun Menon906de572013-06-18 17:01:40 -07009387 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009388}
9389
Arun Menon906de572013-06-18 17:01:40 -07009390void omx_vdec::allocate_color_convert_buf::init_members()
9391{
9392 allocated_count = 0;
9393 buffer_size_req = 0;
9394 buffer_alignment_req = 0;
9395 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9396 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9397 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9398 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009399#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009400 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009401#endif
Arun Menon906de572013-06-18 17:01:40 -07009402 for (int i = 0; i < MAX_COUNT; i++)
9403 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009404}
9405
Arun Menon906de572013-06-18 17:01:40 -07009406omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9407{
9408 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08009409}
9410
9411bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9412{
Arun Menon906de572013-06-18 17:01:40 -07009413 bool status = true;
9414 unsigned int src_size = 0, destination_size = 0;
9415 OMX_COLOR_FORMATTYPE drv_color_format;
9416 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009417 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009418 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009419 }
Arun Menon906de572013-06-18 17:01:40 -07009420 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009421 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07009422 return status;
9423 }
9424 pthread_mutex_lock(&omx->c_lock);
9425 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9426 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009427 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07009428 status = false;
9429 goto fail_update_buf_req;
9430 }
9431 c2d.close();
9432 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9433 omx->drv_ctx.video_resolution.frame_width,
Praveen Chavandb7776f2014-02-06 18:17:25 -08009434 NV12_128m,dest_format);
Arun Menon906de572013-06-18 17:01:40 -07009435 if (status) {
9436 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9437 if (status)
9438 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9439 }
9440 if (status) {
9441 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9442 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009443 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07009444 "driver size %d destination size %d",
9445 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9446 status = false;
9447 c2d.close();
9448 buffer_size_req = 0;
9449 } else {
9450 buffer_size_req = destination_size;
9451 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9452 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9453 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9454 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9455 }
9456 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009457fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07009458 pthread_mutex_unlock(&omx->c_lock);
9459 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009460}
9461
9462bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07009463 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009464{
Arun Menon906de572013-06-18 17:01:40 -07009465 bool status = true;
9466 OMX_COLOR_FORMATTYPE drv_color_format;
9467 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009468 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009469 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009470 }
Arun Menon906de572013-06-18 17:01:40 -07009471 pthread_mutex_lock(&omx->c_lock);
9472 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9473 drv_color_format = (OMX_COLOR_FORMATTYPE)
9474 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9475 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009476 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07009477 status = false;
9478 }
9479 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009480 DEBUG_PRINT_LOW("Enabling C2D");
Praveen Chavandb7776f2014-02-06 18:17:25 -08009481 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
9482 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009483 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009484 status = false;
9485 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009486 ColorFormat = dest_color_format;
9487 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
9488 YCbCr420P : YCbCr420SP;
Arun Menon906de572013-06-18 17:01:40 -07009489 if (enabled)
9490 c2d.destroy();
9491 enabled = false;
9492 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009493 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009494 status = false;
9495 } else
9496 enabled = true;
9497 }
9498 } else {
9499 if (enabled)
9500 c2d.destroy();
9501 enabled = false;
9502 }
9503 pthread_mutex_unlock(&omx->c_lock);
9504 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009505}
9506
9507OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9508{
Arun Menon906de572013-06-18 17:01:40 -07009509 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009510 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009511 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009512 }
Arun Menon906de572013-06-18 17:01:40 -07009513 if (!enabled)
9514 return omx->m_out_mem_ptr;
9515 return m_out_mem_ptr_client;
9516}
9517
9518 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9519(OMX_BUFFERHEADERTYPE *bufadd)
9520{
9521 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009522 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009523 return NULL;
9524 }
9525 if (!enabled)
9526 return bufadd;
9527
9528 unsigned index = 0;
9529 index = bufadd - omx->m_out_mem_ptr;
9530 if (index < omx->drv_ctx.op_buf.actualcount) {
9531 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9532 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9533 bool status;
9534 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9535 pthread_mutex_lock(&omx->c_lock);
9536 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9537 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9538 pmem_baseaddress[index], pmem_baseaddress[index]);
Arun Menon906de572013-06-18 17:01:40 -07009539 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009540 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009541 m_out_mem_ptr_client[index].nFilledLen = 0;
Leena Winterrowd270a7042014-09-30 13:05:55 -07009542 pthread_mutex_unlock(&omx->c_lock);
Arun Menon906de572013-06-18 17:01:40 -07009543 return &m_out_mem_ptr_client[index];
Praveen Chavan6d6b7252014-09-15 17:05:54 -07009544 } else {
9545 unsigned int filledLen = 0;
9546 c2d.get_output_filled_length(filledLen);
9547 m_out_mem_ptr_client[index].nFilledLen = filledLen;
Arun Menon906de572013-06-18 17:01:40 -07009548 }
Leena Winterrowd270a7042014-09-30 13:05:55 -07009549 pthread_mutex_unlock(&omx->c_lock);
Arun Menon906de572013-06-18 17:01:40 -07009550 } else
9551 m_out_mem_ptr_client[index].nFilledLen = 0;
9552 return &m_out_mem_ptr_client[index];
9553 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009554 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009555 return NULL;
9556}
9557
9558 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9559(OMX_BUFFERHEADERTYPE *bufadd)
9560{
9561 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009562 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009563 return NULL;
9564 }
9565 if (!enabled)
9566 return bufadd;
9567 unsigned index = 0;
9568 index = bufadd - m_out_mem_ptr_client;
9569 if (index < omx->drv_ctx.op_buf.actualcount) {
9570 return &omx->m_out_mem_ptr[index];
9571 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009572 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009573 return NULL;
9574}
9575 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9576(unsigned int &buffer_size)
9577{
9578 bool status = true;
9579 pthread_mutex_lock(&omx->c_lock);
9580 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009581 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009582 else {
9583 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009584 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009585 status = false;
9586 goto fail_get_buffer_size;
9587 }
9588 }
9589 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9590 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9591 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9592 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009593fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009594 pthread_mutex_unlock(&omx->c_lock);
9595 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009596}
9597OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009598 OMX_BUFFERHEADERTYPE *bufhdr)
9599{
9600 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009601
Arun Menon906de572013-06-18 17:01:40 -07009602 if (!enabled)
9603 return omx->free_output_buffer(bufhdr);
9604 if (enabled && omx->is_component_secure())
9605 return OMX_ErrorNone;
9606 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009607 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009608 return OMX_ErrorBadParameter;
9609 }
9610 index = bufhdr - m_out_mem_ptr_client;
9611 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009612 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009613 return OMX_ErrorBadParameter;
9614 }
9615 if (pmem_fd[index] > 0) {
9616 munmap(pmem_baseaddress[index], buffer_size_req);
9617 close(pmem_fd[index]);
9618 }
9619 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009620#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009621 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009622#endif
Arun Menon906de572013-06-18 17:01:40 -07009623 m_heap_ptr[index].video_heap_ptr = NULL;
9624 if (allocated_count > 0)
9625 allocated_count--;
9626 else
9627 allocated_count = 0;
9628 if (!allocated_count) {
9629 pthread_mutex_lock(&omx->c_lock);
9630 c2d.close();
9631 init_members();
9632 pthread_mutex_unlock(&omx->c_lock);
9633 }
9634 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009635}
9636
9637OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009638 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009639{
Arun Menon906de572013-06-18 17:01:40 -07009640 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9641 if (!enabled) {
9642 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9643 return eRet;
9644 }
9645 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009646 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009647 omx->is_component_secure());
9648 return OMX_ErrorUnsupportedSetting;
9649 }
9650 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009651 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9652 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009653 buffer_size_req,bytes);
9654 return OMX_ErrorBadParameter;
9655 }
9656 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009657 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009658 return OMX_ErrorInsufficientResources;
9659 }
9660 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9661 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9662 port,appData,omx->drv_ctx.op_buf.buffer_size);
9663 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009664 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009665 return eRet;
9666 }
9667 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309668 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009669 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009670 (temp_bufferHdr - omx->m_out_mem_ptr));
9671 return OMX_ErrorUndefined;
9672 }
9673 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009674#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009675 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9676 buffer_size_req,buffer_alignment_req,
9677 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9678 0);
9679 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9680 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009681 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009682 return OMX_ErrorInsufficientResources;
9683 }
9684 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9685 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009686
Arun Menon906de572013-06-18 17:01:40 -07009687 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009688 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009689 close(pmem_fd[i]);
9690 omx->free_ion_memory(&op_buf_ion_info[i]);
9691 return OMX_ErrorInsufficientResources;
9692 }
9693 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9694 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9695 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009696#endif
Arun Menon906de572013-06-18 17:01:40 -07009697 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9698 m_pmem_info_client[i].offset = 0;
9699 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9700 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9701 m_platform_list_client[i].nEntries = 1;
9702 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9703 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9704 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9705 m_out_mem_ptr_client[i].nFilledLen = 0;
9706 m_out_mem_ptr_client[i].nFlags = 0;
9707 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9708 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9709 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9710 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9711 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9712 m_out_mem_ptr_client[i].pAppPrivate = appData;
9713 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009714 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009715 allocated_count++;
9716 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009717}
9718
9719bool omx_vdec::is_component_secure()
9720{
Arun Menon906de572013-06-18 17:01:40 -07009721 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009722}
9723
9724bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9725{
Arun Menon906de572013-06-18 17:01:40 -07009726 bool status = true;
9727 if (!enabled) {
9728 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9729 dest_color_format = (OMX_COLOR_FORMATTYPE)
9730 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9731 else
9732 status = false;
9733 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009734 if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
9735 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
9736 dest_color_format = ColorFormat;
Arun Menon906de572013-06-18 17:01:40 -07009737 } else
Praveen Chavandb7776f2014-02-06 18:17:25 -08009738 status = false;
Arun Menon906de572013-06-18 17:01:40 -07009739 }
9740 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009741}
Arun Menonbdb80b02013-08-12 17:45:54 -07009742
Arun Menonbdb80b02013-08-12 17:45:54 -07009743void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9744{
9745 int i = 0;
9746 bool buf_present = false;
9747 pthread_mutex_lock(&m_lock);
9748 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9749 //check the buffer fd, offset, uv addr with list contents
9750 //If present increment reference.
9751 if ((out_dynamic_list[i].fd == fd) &&
9752 (out_dynamic_list[i].offset == offset)) {
9753 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009754 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009755 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9756 buf_present = true;
9757 break;
9758 }
9759 }
9760 if (!buf_present) {
9761 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9762 //search for a entry to insert details of the new buffer
9763 if (out_dynamic_list[i].dup_fd == 0) {
9764 out_dynamic_list[i].fd = fd;
9765 out_dynamic_list[i].offset = offset;
9766 out_dynamic_list[i].dup_fd = dup(fd);
9767 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009768 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009769 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9770 break;
9771 }
9772 }
9773 }
9774 pthread_mutex_unlock(&m_lock);
9775}
9776
9777void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9778{
9779 int i = 0;
9780 pthread_mutex_lock(&m_lock);
9781 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9782 //check the buffer fd, offset, uv addr with list contents
9783 //If present decrement reference.
9784 if ((out_dynamic_list[i].fd == fd) &&
9785 (out_dynamic_list[i].offset == offset)) {
9786 out_dynamic_list[i].ref_count--;
9787 if (out_dynamic_list[i].ref_count == 0) {
9788 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009789 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009790 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9791 out_dynamic_list[i].dup_fd = 0;
9792 out_dynamic_list[i].fd = 0;
9793 out_dynamic_list[i].offset = 0;
9794 }
9795 break;
9796 }
9797 }
9798 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009799 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009800 }
9801 pthread_mutex_unlock(&m_lock);
9802}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009803
Arun Menon1fc764f2014-04-17 15:41:27 -07009804OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
9805 unsigned long nMaxFrameHeight)
9806{
9807
9808 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9809 int ret = 0;
9810 unsigned long min_res_buf_count = 0;
9811
9812 eRet = enable_smoothstreaming();
9813 if (eRet != OMX_ErrorNone) {
9814 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
9815 return eRet;
9816 }
9817
9818 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
9819 nMaxFrameWidth,
9820 nMaxFrameHeight);
9821 m_smoothstreaming_mode = true;
9822 m_smoothstreaming_width = nMaxFrameWidth;
9823 m_smoothstreaming_height = nMaxFrameHeight;
9824
9825 //Get upper limit buffer count for min supported resolution
9826 struct v4l2_format fmt;
9827 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9828 fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
9829 fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
9830 fmt.fmt.pix_mp.pixelformat = output_capability;
9831
9832 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9833 if (ret) {
9834 DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
9835 m_decoder_capability.min_height,
9836 m_decoder_capability.min_width);
9837 return OMX_ErrorUnsupportedSetting;
9838 }
9839
9840 eRet = get_buffer_req(&drv_ctx.op_buf);
9841 if (eRet != OMX_ErrorNone) {
9842 DEBUG_PRINT_ERROR("failed to get_buffer_req");
9843 return eRet;
9844 }
9845
9846 min_res_buf_count = drv_ctx.op_buf.mincount;
9847 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
9848 min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
9849
9850 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
9851 m_smoothstreaming_width, m_smoothstreaming_height);
9852 eRet = is_video_session_supported();
9853 if (eRet != OMX_ErrorNone) {
9854 DEBUG_PRINT_ERROR("video session is not supported");
9855 return eRet;
9856 }
9857
9858 //Get upper limit buffer size for max smooth streaming resolution set
9859 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9860 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
9861 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
9862 fmt.fmt.pix_mp.pixelformat = output_capability;
9863 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9864 if (ret) {
9865 DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
9866 return OMX_ErrorUnsupportedSetting;
9867 }
9868
9869 eRet = get_buffer_req(&drv_ctx.op_buf);
9870 if (eRet != OMX_ErrorNone) {
9871 DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
9872 return eRet;
9873 }
9874 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
9875 drv_ctx.op_buf.buffer_size);
9876
9877 drv_ctx.op_buf.mincount = min_res_buf_count;
9878 drv_ctx.op_buf.actualcount = min_res_buf_count;
9879 eRet = set_buffer_req(&drv_ctx.op_buf);
9880 if (eRet != OMX_ErrorNone) {
9881 DEBUG_PRINT_ERROR("failed to set_buffer_req");
9882 return eRet;
9883 }
9884
9885 eRet = get_buffer_req(&drv_ctx.op_buf);
9886 if (eRet != OMX_ErrorNone) {
9887 DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
9888 return eRet;
9889 }
9890 DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
9891 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size);
9892 return eRet;
9893}
9894
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009895#ifdef _MSM8974_
9896void omx_vdec::send_codec_config() {
9897 if (codec_config_flag) {
9898 unsigned p1 = 0; // Parameter - 1
9899 unsigned p2 = 0; // Parameter - 2
9900 unsigned ident = 0;
9901 pthread_mutex_lock(&m_lock);
9902 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9903 while (m_etb_q.m_size) {
9904 m_etb_q.pop_entry(&p1,&p2,&ident);
9905 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9906 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9907 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9908 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9909 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9910 omx_report_error();
9911 }
9912 } else {
9913 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9914 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9915 }
9916 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9917 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9918 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9919 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9920 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9921 omx_report_error ();
9922 }
9923 } else {
9924 pending_input_buffers++;
9925 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9926 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9927 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9928 }
9929 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9930 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9931 (OMX_BUFFERHEADERTYPE *)p1);
9932 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9933 }
9934 }
9935 pthread_mutex_unlock(&m_lock);
9936 }
9937}
9938#endif
Praveen Chavan09a82b72014-10-18 09:09:45 -07009939
9940//static
9941OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
9942
9943#ifndef FLEXYUV_SUPPORTED
9944 (void)pParam;
9945 return OMX_ErrorUndefined;
9946#else
9947
9948 if (pParam == NULL) {
9949 DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
9950 return OMX_ErrorBadParameter;
9951 }
9952
9953 DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
9954
9955 MediaImage *img = &(params->sMediaImage);
9956 switch(params->eColorFormat) {
9957 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
9958 {
9959 img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
9960 img->mNumPlanes = 3;
9961 // mWidth and mHeight represent the W x H of the largest plane
9962 // In our case, this happens to be the Stride x Scanlines of Y plane
9963 img->mWidth = params->nFrameWidth;
9964 img->mHeight = params->nFrameHeight;
9965 size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
9966 size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
9967 img->mBitDepth = 8;
9968 //Plane 0 (Y)
9969 img->mPlane[MediaImage::Y].mOffset = 0;
9970 img->mPlane[MediaImage::Y].mColInc = 1;
9971 img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
9972 img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
9973 img->mPlane[MediaImage::Y].mVertSubsampling = 1;
9974 //Plane 1 (U)
9975 img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
9976 img->mPlane[MediaImage::U].mColInc = 2; //interleaved UV
9977 img->mPlane[MediaImage::U].mRowInc =
9978 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
9979 img->mPlane[MediaImage::U].mHorizSubsampling = 2;
9980 img->mPlane[MediaImage::U].mVertSubsampling = 2;
9981 //Plane 2 (V)
9982 img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
9983 img->mPlane[MediaImage::V].mColInc = 2; //interleaved UV
9984 img->mPlane[MediaImage::V].mRowInc =
9985 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
9986 img->mPlane[MediaImage::V].mHorizSubsampling = 2;
9987 img->mPlane[MediaImage::V].mVertSubsampling = 2;
9988 break;
9989 }
9990
9991 case OMX_COLOR_FormatYUV420Planar:
9992 case OMX_COLOR_FormatYUV420SemiPlanar:
9993 // We need not describe the standard OMX linear formats as these are
9994 // understood by client. Fail this deliberately to let client fill-in
9995 return OMX_ErrorUnsupportedSetting;
9996
9997 default:
9998 // Rest all formats which are non-linear cannot be described
9999 DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
10000 img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
10001 return OMX_ErrorNone;
10002 };
10003
10004 DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
10005 DEBUG_PRINT_LOW(" FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
10006 DEBUG_PRINT_LOW(" YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
10007 for (size_t i = 0; i < img->mNumPlanes; ++i) {
10008 DEBUG_PRINT_LOW(" Plane[%d] : offset=%d / xStep=%d / yStep = %d",
10009 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
10010 }
10011 return OMX_ErrorNone;
10012#endif //FLEXYUV_SUPPORTED
10013}
10014