blob: 28afac894f99608d5c2cc6c4146e9d7c9d1cdcef [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));
Praveen Chavan898df262015-04-20 18:52:19 -07001951 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
1952 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
1953
1954 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
1955 DEBUG_PRINT_ERROR("Failed to set Default Priority");
1956 eRet = OMX_ErrorUnsupportedSetting;
1957 }
Arun Menon906de572013-06-18 17:01:40 -07001958 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001959}
1960
1961/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001962 FUNCTION
1963 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001964
Arun Menon906de572013-06-18 17:01:40 -07001965 DESCRIPTION
1966 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001967
Arun Menon906de572013-06-18 17:01:40 -07001968 PARAMETERS
1969 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001970
Arun Menon906de572013-06-18 17:01:40 -07001971 RETURN VALUE
1972 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001973
Arun Menon906de572013-06-18 17:01:40 -07001974 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001975OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001976(
1977 OMX_IN OMX_HANDLETYPE hComp,
1978 OMX_OUT OMX_STRING componentName,
1979 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1980 OMX_OUT OMX_VERSIONTYPE* specVersion,
1981 OMX_OUT OMX_UUIDTYPE* componentUUID
1982 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001983{
Arun Menon906de572013-06-18 17:01:40 -07001984 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001985 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001986 return OMX_ErrorInvalidState;
1987 }
Arun Menon906de572013-06-18 17:01:40 -07001988 /* TBD -- Return the proper version */
1989 if (specVersion) {
1990 specVersion->nVersion = OMX_SPEC_VERSION;
1991 }
1992 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001993}
1994/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001995 FUNCTION
1996 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001997
Arun Menon906de572013-06-18 17:01:40 -07001998 DESCRIPTION
1999 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07002000
Arun Menon906de572013-06-18 17:01:40 -07002001 PARAMETERS
2002 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002003
Arun Menon906de572013-06-18 17:01:40 -07002004 RETURN VALUE
2005 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002006
Arun Menon906de572013-06-18 17:01:40 -07002007 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002008OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002009 OMX_IN OMX_COMMANDTYPE cmd,
2010 OMX_IN OMX_U32 param1,
2011 OMX_IN OMX_PTR cmdData
2012 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002013{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002014 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07002015 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002016 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002017 return OMX_ErrorInvalidState;
2018 }
2019 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07002020 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002021 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07002022 "to invalid port: %lu", param1);
2023 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002024 }
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -07002025
Shalaj Jain273b3e02012-06-22 19:08:03 -07002026 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
2027 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002028 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002029 return OMX_ErrorNone;
2030}
2031
2032/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002033 FUNCTION
2034 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07002035
Arun Menon906de572013-06-18 17:01:40 -07002036 DESCRIPTION
2037 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07002038
Arun Menon906de572013-06-18 17:01:40 -07002039 PARAMETERS
2040 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002041
Arun Menon906de572013-06-18 17:01:40 -07002042 RETURN VALUE
2043 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002044
Arun Menon906de572013-06-18 17:01:40 -07002045 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002046OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002047 OMX_IN OMX_COMMANDTYPE cmd,
2048 OMX_IN OMX_U32 param1,
2049 OMX_IN OMX_PTR cmdData
2050 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002051{
Arun Menon906de572013-06-18 17:01:40 -07002052 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2053 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
2054 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002055
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002056 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
2057 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07002058 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002059
Arun Menon906de572013-06-18 17:01:40 -07002060 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002061 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
2062 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07002063 /***************************/
2064 /* Current State is Loaded */
2065 /***************************/
2066 if (m_state == OMX_StateLoaded) {
2067 if (eState == OMX_StateIdle) {
2068 //if all buffers are allocated or all ports disabled
2069 if (allocate_done() ||
2070 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002071 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002072 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002073 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002074 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
2075 // Skip the event notification
2076 bFlag = 0;
2077 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002078 }
Arun Menon906de572013-06-18 17:01:40 -07002079 /* Requesting transition from Loaded to Loaded */
2080 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002081 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002082 post_event(OMX_EventError,OMX_ErrorSameState,\
2083 OMX_COMPONENT_GENERATE_EVENT);
2084 eRet = OMX_ErrorSameState;
2085 }
2086 /* Requesting transition from Loaded to WaitForResources */
2087 else if (eState == OMX_StateWaitForResources) {
2088 /* Since error is None , we will post an event
2089 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002090 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002091 }
2092 /* Requesting transition from Loaded to Executing */
2093 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002094 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
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 Pause */
2100 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002101 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002102 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2103 OMX_COMPONENT_GENERATE_EVENT);
2104 eRet = OMX_ErrorIncorrectStateTransition;
2105 }
2106 /* Requesting transition from Loaded to Invalid */
2107 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002108 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002109 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2110 eRet = OMX_ErrorInvalidState;
2111 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002112 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07002113 eState);
2114 eRet = OMX_ErrorBadParameter;
2115 }
2116 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002117
Arun Menon906de572013-06-18 17:01:40 -07002118 /***************************/
2119 /* Current State is IDLE */
2120 /***************************/
2121 else if (m_state == OMX_StateIdle) {
2122 if (eState == OMX_StateLoaded) {
2123 if (release_done()) {
2124 /*
2125 Since error is None , we will post an event at the end
2126 of this function definition
2127 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002128 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002129 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002130 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002131 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2132 // Skip the event notification
2133 bFlag = 0;
2134 }
2135 }
2136 /* Requesting transition from Idle to Executing */
2137 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002138 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002139 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2140 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002141 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002142 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002143 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07002144 }
2145 /* Requesting transition from Idle to Idle */
2146 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002147 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002148 post_event(OMX_EventError,OMX_ErrorSameState,\
2149 OMX_COMPONENT_GENERATE_EVENT);
2150 eRet = OMX_ErrorSameState;
2151 }
2152 /* Requesting transition from Idle to WaitForResources */
2153 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002154 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002155 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2156 OMX_COMPONENT_GENERATE_EVENT);
2157 eRet = OMX_ErrorIncorrectStateTransition;
2158 }
2159 /* Requesting transition from Idle to Pause */
2160 else if (eState == OMX_StatePause) {
2161 /*To pause the Video core we need to start the driver*/
2162 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2163 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002164 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002165 omx_report_error ();
2166 eRet = OMX_ErrorHardware;
2167 } else {
2168 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002169 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002170 bFlag = 0;
2171 }
2172 }
2173 /* Requesting transition from Idle to Invalid */
2174 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002175 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002176 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2177 eRet = OMX_ErrorInvalidState;
2178 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002179 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002180 eRet = OMX_ErrorBadParameter;
2181 }
2182 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002183
Arun Menon906de572013-06-18 17:01:40 -07002184 /******************************/
2185 /* Current State is Executing */
2186 /******************************/
2187 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002188 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002189 /* Requesting transition from Executing to Idle */
2190 if (eState == OMX_StateIdle) {
2191 /* Since error is None , we will post an event
2192 at the end of this function definition
2193 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002194 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002195 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2196 if (!sem_posted) {
2197 sem_posted = 1;
2198 sem_post (&m_cmd_lock);
2199 execute_omx_flush(OMX_ALL);
2200 }
2201 bFlag = 0;
2202 }
2203 /* Requesting transition from Executing to Paused */
2204 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002205 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002206 m_state = OMX_StatePause;
2207 bFlag = 1;
2208 }
2209 /* Requesting transition from Executing to Loaded */
2210 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002211 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
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 WaitForResources */
2217 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002218 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002219 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2220 OMX_COMPONENT_GENERATE_EVENT);
2221 eRet = OMX_ErrorIncorrectStateTransition;
2222 }
2223 /* Requesting transition from Executing to Executing */
2224 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002225 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002226 post_event(OMX_EventError,OMX_ErrorSameState,\
2227 OMX_COMPONENT_GENERATE_EVENT);
2228 eRet = OMX_ErrorSameState;
2229 }
2230 /* Requesting transition from Executing to Invalid */
2231 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002232 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002233 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2234 eRet = OMX_ErrorInvalidState;
2235 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002236 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002237 eRet = OMX_ErrorBadParameter;
2238 }
2239 }
2240 /***************************/
2241 /* Current State is Pause */
2242 /***************************/
2243 else if (m_state == OMX_StatePause) {
2244 /* Requesting transition from Pause to Executing */
2245 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002246 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002247 m_state = OMX_StateExecuting;
2248 bFlag = 1;
2249 }
2250 /* Requesting transition from Pause to Idle */
2251 else if (eState == OMX_StateIdle) {
2252 /* Since error is None , we will post an event
2253 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002254 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002255 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2256 if (!sem_posted) {
2257 sem_posted = 1;
2258 sem_post (&m_cmd_lock);
2259 execute_omx_flush(OMX_ALL);
2260 }
2261 bFlag = 0;
2262 }
2263 /* Requesting transition from Pause to loaded */
2264 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002265 DEBUG_PRINT_ERROR("Pause --> loaded");
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 WaitForResources */
2271 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002272 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002273 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2274 OMX_COMPONENT_GENERATE_EVENT);
2275 eRet = OMX_ErrorIncorrectStateTransition;
2276 }
2277 /* Requesting transition from Pause to Pause */
2278 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002279 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002280 post_event(OMX_EventError,OMX_ErrorSameState,\
2281 OMX_COMPONENT_GENERATE_EVENT);
2282 eRet = OMX_ErrorSameState;
2283 }
2284 /* Requesting transition from Pause to Invalid */
2285 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002286 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002287 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2288 eRet = OMX_ErrorInvalidState;
2289 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002290 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002291 eRet = OMX_ErrorBadParameter;
2292 }
2293 }
2294 /***************************/
2295 /* Current State is WaitForResources */
2296 /***************************/
2297 else if (m_state == OMX_StateWaitForResources) {
2298 /* Requesting transition from WaitForResources to Loaded */
2299 if (eState == OMX_StateLoaded) {
2300 /* Since error is None , we will post an event
2301 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002302 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002303 }
2304 /* Requesting transition from WaitForResources to WaitForResources */
2305 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002306 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002307 post_event(OMX_EventError,OMX_ErrorSameState,
2308 OMX_COMPONENT_GENERATE_EVENT);
2309 eRet = OMX_ErrorSameState;
2310 }
2311 /* Requesting transition from WaitForResources to Executing */
2312 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002313 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
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 Pause */
2319 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002320 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002321 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2322 OMX_COMPONENT_GENERATE_EVENT);
2323 eRet = OMX_ErrorIncorrectStateTransition;
2324 }
2325 /* Requesting transition from WaitForResources to Invalid */
2326 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002327 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002328 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2329 eRet = OMX_ErrorInvalidState;
2330 }
2331 /* Requesting transition from WaitForResources to Loaded -
2332 is NOT tested by Khronos TS */
2333
2334 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002335 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002336 eRet = OMX_ErrorBadParameter;
2337 }
2338 }
2339 /********************************/
2340 /* Current State is Invalid */
2341 /*******************************/
2342 else if (m_state == OMX_StateInvalid) {
2343 /* State Transition from Inavlid to any state */
2344 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2345 || OMX_StateIdle || OMX_StateExecuting
2346 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002347 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002348 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2349 OMX_COMPONENT_GENERATE_EVENT);
2350 eRet = OMX_ErrorInvalidState;
2351 }
2352 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002353 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002354 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002355#ifdef _MSM8974_
2356 send_codec_config();
2357#endif
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302358 if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
2359 param1 == OMX_ALL)) {
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05302360 if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302361 struct timespec ts;
2362
2363 clock_gettime(CLOCK_REALTIME, &ts);
2364 ts.tv_sec += 2;
2365 DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
2366 m_queued_codec_config_count);
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05302367 BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302368 if (sem_timedwait(&m_safe_flush, &ts)) {
2369 DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302370 }
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05302371 BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302372 }
2373 }
2374
Arun Menon906de572013-06-18 17:01:40 -07002375 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2376 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2377 }
2378 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2379 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2380 }
2381 if (!sem_posted) {
2382 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002383 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002384 sem_post (&m_cmd_lock);
2385 execute_omx_flush(param1);
2386 }
2387 bFlag = 0;
2388 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002389 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002390 "with param1: %lu", param1);
2391 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2392 m_inp_bEnabled = OMX_TRUE;
2393
2394 if ( (m_state == OMX_StateLoaded &&
2395 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2396 || allocate_input_done()) {
2397 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2398 OMX_COMPONENT_GENERATE_EVENT);
2399 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002400 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002401 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2402 // Skip the event notification
2403 bFlag = 0;
2404 }
2405 }
2406 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002407 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002408 m_out_bEnabled = OMX_TRUE;
2409
2410 if ( (m_state == OMX_StateLoaded &&
2411 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2412 || (allocate_output_done())) {
2413 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2414 OMX_COMPONENT_GENERATE_EVENT);
2415
2416 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002417 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002418 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2419 // Skip the event notification
2420 bFlag = 0;
2421 }
2422 }
2423 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002424 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002425 "with param1: %lu", param1);
2426 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002427 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002428 m_inp_bEnabled = OMX_FALSE;
2429 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2430 && release_input_done()) {
2431 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2432 OMX_COMPONENT_GENERATE_EVENT);
2433 } else {
2434 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2435 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2436 if (!sem_posted) {
2437 sem_posted = 1;
2438 sem_post (&m_cmd_lock);
2439 }
2440 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2441 }
2442
2443 // Skip the event notification
2444 bFlag = 0;
2445 }
2446 }
2447 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2448 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002449 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002450 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2451 && release_output_done()) {
2452 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2453 OMX_COMPONENT_GENERATE_EVENT);
2454 } else {
2455 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2456 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2457 if (!sem_posted) {
2458 sem_posted = 1;
2459 sem_post (&m_cmd_lock);
2460 }
2461 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2462 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2463 }
2464 // Skip the event notification
2465 bFlag = 0;
2466
2467 }
2468 }
2469 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002470 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002471 eRet = OMX_ErrorNotImplemented;
2472 }
2473 if (eRet == OMX_ErrorNone && bFlag) {
2474 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2475 }
2476 if (!sem_posted) {
2477 sem_post(&m_cmd_lock);
2478 }
2479
2480 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002481}
2482
2483/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002484 FUNCTION
2485 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002486
Arun Menon906de572013-06-18 17:01:40 -07002487 DESCRIPTION
2488 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002489
Arun Menon906de572013-06-18 17:01:40 -07002490 PARAMETERS
2491 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002492
Arun Menon906de572013-06-18 17:01:40 -07002493 RETURN VALUE
2494 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002495
Arun Menon906de572013-06-18 17:01:40 -07002496 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002497bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2498{
Arun Menon906de572013-06-18 17:01:40 -07002499 bool bRet = false;
2500 struct v4l2_plane plane;
2501 struct v4l2_buffer v4l2_buf;
2502 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302503 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002504 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2505 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002506
Arun Menon906de572013-06-18 17:01:40 -07002507 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002508
Arun Menon906de572013-06-18 17:01:40 -07002509 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2510 output_flush_progress = true;
2511 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2512 } else {
2513 /* XXX: The driver/hardware does not support flushing of individual ports
2514 * in all states. So we pretty much need to flush both ports internally,
2515 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2516 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2517 * we automatically omit sending the FLUSH done for the "opposite" port. */
2518 input_flush_progress = true;
2519 output_flush_progress = true;
2520 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2521 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002522
Arun Menon906de572013-06-18 17:01:40 -07002523 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002524 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002525 bRet = false;
2526 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002527
Arun Menon906de572013-06-18 17:01:40 -07002528 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002529}
2530/*=========================================================================
2531FUNCTION : execute_output_flush
2532
2533DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002534Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002535
2536PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002537None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002538
2539RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002540true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002541==========================================================================*/
2542bool omx_vdec::execute_output_flush()
2543{
Arun Menon906de572013-06-18 17:01:40 -07002544 unsigned p1 = 0; // Parameter - 1
2545 unsigned p2 = 0; // Parameter - 2
2546 unsigned ident = 0;
2547 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002548
Arun Menon906de572013-06-18 17:01:40 -07002549 /*Generate FBD for all Buffers in the FTBq*/
2550 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002551 DEBUG_PRINT_LOW("Initiate Output Flush");
vivek mehta79cff222014-01-22 12:17:07 -08002552
2553 //reset last render TS
2554 if(m_last_rendered_TS > 0) {
2555 m_last_rendered_TS = 0;
2556 }
vivek mehtaa75c69f2014-01-10 21:50:37 -08002557
Arun Menon906de572013-06-18 17:01:40 -07002558 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002559 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002560 m_ftb_q.m_size,pending_output_buffers);
2561 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002562 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002563 if (ident == m_fill_output_msg ) {
2564 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2565 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2566 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2567 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002568 }
Arun Menon906de572013-06-18 17:01:40 -07002569 pthread_mutex_unlock(&m_lock);
2570 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002571
Arun Menon906de572013-06-18 17:01:40 -07002572 if (arbitrary_bytes) {
2573 prev_ts = LLONG_MAX;
2574 rst_prev_ts = true;
2575 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002576 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002577 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002578}
2579/*=========================================================================
2580FUNCTION : execute_input_flush
2581
2582DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002583Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002584
2585PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002586None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002587
2588RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002589true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002590==========================================================================*/
2591bool omx_vdec::execute_input_flush()
2592{
Arun Menon906de572013-06-18 17:01:40 -07002593 unsigned i =0;
2594 unsigned p1 = 0; // Parameter - 1
2595 unsigned p2 = 0; // Parameter - 2
2596 unsigned ident = 0;
2597 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002598
Arun Menon906de572013-06-18 17:01:40 -07002599 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002600 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002601
Arun Menon906de572013-06-18 17:01:40 -07002602 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002603 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002604 while (m_etb_q.m_size) {
2605 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002606
Arun Menon906de572013-06-18 17:01:40 -07002607 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002608 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002609 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2610 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2611 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002612 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002613 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2614 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2615 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002616 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002617 (OMX_BUFFERHEADERTYPE *)p1);
2618 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2619 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002620 }
Arun Menon906de572013-06-18 17:01:40 -07002621 time_stamp_dts.flush_timestamp();
2622 /*Check if Heap Buffers are to be flushed*/
2623 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002624 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002625 h264_scratch.nFilledLen = 0;
2626 nal_count = 0;
2627 look_ahead_nal = false;
2628 frame_count = 0;
2629 h264_last_au_ts = LLONG_MAX;
2630 h264_last_au_flags = 0;
2631 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2632 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002633 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002634 if (m_frame_parser.mutils) {
2635 m_frame_parser.mutils->initialize_frame_checking_environment();
2636 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002637
Arun Menon906de572013-06-18 17:01:40 -07002638 while (m_input_pending_q.m_size) {
2639 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2640 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2641 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002642
Arun Menon906de572013-06-18 17:01:40 -07002643 if (psource_frame) {
2644 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2645 psource_frame = NULL;
2646 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002647
Arun Menon906de572013-06-18 17:01:40 -07002648 if (pdest_frame) {
2649 pdest_frame->nFilledLen = 0;
2650 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2651 (unsigned int)NULL);
2652 pdest_frame = NULL;
2653 }
2654 m_frame_parser.flush();
2655 } else if (codec_config_flag) {
2656 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2657 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002658 }
Arun Menon906de572013-06-18 17:01:40 -07002659 pthread_mutex_unlock(&m_lock);
2660 input_flush_progress = false;
2661 if (!arbitrary_bytes) {
2662 prev_ts = LLONG_MAX;
2663 rst_prev_ts = true;
2664 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002665#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002666 if (m_debug_timestamp) {
2667 m_timestamp_list.reset_ts_list();
2668 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002669#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002670 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002671 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002672}
2673
2674
2675/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002676 FUNCTION
2677 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002678
Arun Menon906de572013-06-18 17:01:40 -07002679 DESCRIPTION
2680 Send the event to decoder pipe. This is needed to generate the callbacks
2681 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002682
Arun Menon906de572013-06-18 17:01:40 -07002683 PARAMETERS
2684 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002685
Arun Menon906de572013-06-18 17:01:40 -07002686 RETURN VALUE
2687 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002688
Arun Menon906de572013-06-18 17:01:40 -07002689 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002690bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002691 unsigned int p2,
2692 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002693{
Arun Menon906de572013-06-18 17:01:40 -07002694 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002695
2696
Arun Menon906de572013-06-18 17:01:40 -07002697 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002698
Arun Menon906de572013-06-18 17:01:40 -07002699 if (id == m_fill_output_msg ||
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05302700 id == OMX_COMPONENT_GENERATE_FBD ||
2701 id == OMX_COMPONENT_GENERATE_PORT_RECONFIG) {
Arun Menon906de572013-06-18 17:01:40 -07002702 m_ftb_q.insert_entry(p1,p2,id);
2703 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2704 id == OMX_COMPONENT_GENERATE_EBD ||
2705 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2706 m_etb_q.insert_entry(p1,p2,id);
2707 } else {
2708 m_cmd_q.insert_entry(p1,p2,id);
2709 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002710
Arun Menon906de572013-06-18 17:01:40 -07002711 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002712 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002713 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002714
Arun Menon906de572013-06-18 17:01:40 -07002715 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002716
Arun Menon906de572013-06-18 17:01:40 -07002717 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002718}
2719
2720OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2721{
Arun Menon906de572013-06-18 17:01:40 -07002722 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2723 if (!profileLevelType)
2724 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002725
Arun Menon906de572013-06-18 17:01:40 -07002726 if (profileLevelType->nPortIndex == 0) {
2727 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2728 if (profileLevelType->nProfileIndex == 0) {
2729 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2730 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002731
Arun Menon906de572013-06-18 17:01:40 -07002732 } else if (profileLevelType->nProfileIndex == 1) {
2733 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2734 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2735 } else if (profileLevelType->nProfileIndex == 2) {
2736 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2737 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2738 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002739 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002740 profileLevelType->nProfileIndex);
2741 eRet = OMX_ErrorNoMore;
2742 }
2743 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2744 if (profileLevelType->nProfileIndex == 0) {
2745 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2746 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2747 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002748 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002749 eRet = OMX_ErrorNoMore;
2750 }
2751 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2752 if (profileLevelType->nProfileIndex == 0) {
2753 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2754 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2755 } else if (profileLevelType->nProfileIndex == 1) {
2756 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2757 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2758 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002759 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002760 eRet = OMX_ErrorNoMore;
2761 }
2762 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2763 eRet = OMX_ErrorNoMore;
2764 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2765 if (profileLevelType->nProfileIndex == 0) {
2766 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2767 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2768 } else if (profileLevelType->nProfileIndex == 1) {
2769 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2770 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2771 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002772 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002773 eRet = OMX_ErrorNoMore;
2774 }
2775 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002776 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002777 eRet = OMX_ErrorNoMore;
2778 }
2779 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002780 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002781 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002782 }
Arun Menon906de572013-06-18 17:01:40 -07002783 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002784}
2785
2786/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002787 FUNCTION
2788 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002789
Arun Menon906de572013-06-18 17:01:40 -07002790 DESCRIPTION
2791 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002792
Arun Menon906de572013-06-18 17:01:40 -07002793 PARAMETERS
2794 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002795
Arun Menon906de572013-06-18 17:01:40 -07002796 RETURN VALUE
2797 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002798
Arun Menon906de572013-06-18 17:01:40 -07002799 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002800OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002801 OMX_IN OMX_INDEXTYPE paramIndex,
2802 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002803{
2804 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2805
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002806 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002807 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002808 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002809 return OMX_ErrorInvalidState;
2810 }
Arun Menon906de572013-06-18 17:01:40 -07002811 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002812 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002813 return OMX_ErrorBadParameter;
2814 }
Arun Menon906de572013-06-18 17:01:40 -07002815 switch ((unsigned long)paramIndex) {
2816 case OMX_IndexParamPortDefinition: {
2817 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2818 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002819 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002820 eRet = update_portdef(portDefn);
2821 if (eRet == OMX_ErrorNone)
2822 m_port_def = *portDefn;
2823 break;
2824 }
2825 case OMX_IndexParamVideoInit: {
2826 OMX_PORT_PARAM_TYPE *portParamType =
2827 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002828 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002829
Arun Menon906de572013-06-18 17:01:40 -07002830 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2831 portParamType->nSize = sizeof(portParamType);
2832 portParamType->nPorts = 2;
2833 portParamType->nStartPortNumber = 0;
2834 break;
2835 }
2836 case OMX_IndexParamVideoPortFormat: {
2837 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2838 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002839 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002840
Arun Menon906de572013-06-18 17:01:40 -07002841 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2842 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002843
Arun Menon906de572013-06-18 17:01:40 -07002844 if (0 == portFmt->nPortIndex) {
2845 if (0 == portFmt->nIndex) {
2846 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2847 portFmt->eCompressionFormat = eCompressionFormat;
2848 } else {
2849 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002850 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002851 eRet = OMX_ErrorNoMore;
2852 }
2853 } else if (1 == portFmt->nPortIndex) {
2854 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002855
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07002856 // Distinguish non-surface mode from normal playback use-case based on
2857 // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
2858 // For non-android, use the default list
Praveen Chavancac86402014-10-18 09:14:52 -07002859 // Also use default format-list if FLEXIBLE YUV is supported,
2860 // as the client negotiates the standard color-format if it needs to
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07002861 bool useNonSurfaceMode = false;
Praveen Chavancac86402014-10-18 09:14:52 -07002862#if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED)
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07002863 useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
2864#endif
2865 portFmt->eColorFormat = useNonSurfaceMode ?
2866 getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
2867 getPreferredColorFormatDefaultMode(portFmt->nIndex);
2868
2869 if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
Praveen Chavandb7776f2014-02-06 18:17:25 -08002870 eRet = OMX_ErrorNoMore;
Arun Menon906de572013-06-18 17:01:40 -07002871 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002872 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002873 }
Praveen Chavandb7776f2014-02-06 18:17:25 -08002874 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002875 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002876 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002877 (int)portFmt->nPortIndex);
2878 eRet = OMX_ErrorBadPortIndex;
2879 }
2880 break;
2881 }
2882 /*Component should support this port definition*/
2883 case OMX_IndexParamAudioInit: {
2884 OMX_PORT_PARAM_TYPE *audioPortParamType =
2885 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002886 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002887 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2888 audioPortParamType->nSize = sizeof(audioPortParamType);
2889 audioPortParamType->nPorts = 0;
2890 audioPortParamType->nStartPortNumber = 0;
2891 break;
2892 }
2893 /*Component should support this port definition*/
2894 case OMX_IndexParamImageInit: {
2895 OMX_PORT_PARAM_TYPE *imagePortParamType =
2896 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002897 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002898 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2899 imagePortParamType->nSize = sizeof(imagePortParamType);
2900 imagePortParamType->nPorts = 0;
2901 imagePortParamType->nStartPortNumber = 0;
2902 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002903
Arun Menon906de572013-06-18 17:01:40 -07002904 }
2905 /*Component should support this port definition*/
2906 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002907 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002908 paramIndex);
2909 eRet =OMX_ErrorUnsupportedIndex;
2910 break;
2911 }
2912 case OMX_IndexParamStandardComponentRole: {
2913 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2914 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2915 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2916 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002917
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002918 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002919 paramIndex);
2920 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2921 OMX_MAX_STRINGNAME_SIZE);
2922 break;
2923 }
2924 /* Added for parameter test */
2925 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002926
Arun Menon906de572013-06-18 17:01:40 -07002927 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2928 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002929 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002930 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2931 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002932
Arun Menon906de572013-06-18 17:01:40 -07002933 break;
2934 }
2935 /* Added for parameter test */
2936 case OMX_IndexParamCompBufferSupplier: {
2937 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2938 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002939 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002940
Arun Menon906de572013-06-18 17:01:40 -07002941 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2942 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2943 if (0 == bufferSupplierType->nPortIndex)
2944 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2945 else if (1 == bufferSupplierType->nPortIndex)
2946 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2947 else
2948 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002949
2950
Arun Menon906de572013-06-18 17:01:40 -07002951 break;
2952 }
2953 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002954 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002955 paramIndex);
2956 break;
2957 }
2958 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002959 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002960 paramIndex);
2961 break;
2962 }
2963 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002964 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002965 paramIndex);
2966 break;
2967 }
2968 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002969 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002970 paramIndex);
2971 break;
2972 }
2973 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002974 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002975 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2976 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2977 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2978 break;
2979 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002980#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002981 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002982 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002983 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2984 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002985
Arun Menon906de572013-06-18 17:01:40 -07002986 if (secure_mode) {
2987 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2988 GRALLOC_USAGE_PRIVATE_UNCACHED);
2989 } else {
2990 nativeBuffersUsage->nUsage =
2991 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2992 GRALLOC_USAGE_PRIVATE_UNCACHED);
2993 }
2994 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002995 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002996 eRet = OMX_ErrorBadParameter;
2997 }
2998 }
2999 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003000#endif
3001
Praveen Chavan09a82b72014-10-18 09:09:45 -07003002#ifdef FLEXYUV_SUPPORTED
3003 case OMX_QcomIndexFlexibleYUVDescription: {
3004 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
3005 eRet = describeColorFormat(paramData);
3006 break;
3007 }
3008#endif
3009
Arun Menon906de572013-06-18 17:01:40 -07003010 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003011 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003012 eRet =OMX_ErrorUnsupportedIndex;
3013 }
3014
Shalaj Jain273b3e02012-06-22 19:08:03 -07003015 }
3016
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003017 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07003018 drv_ctx.video_resolution.frame_width,
3019 drv_ctx.video_resolution.frame_height,
3020 drv_ctx.video_resolution.stride,
3021 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003022
Arun Menon906de572013-06-18 17:01:40 -07003023 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003024}
3025
3026#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3027OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
3028{
3029 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
3030 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3031 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
3032
Arun Menon906de572013-06-18 17:01:40 -07003033 if ((params == NULL) ||
3034 (params->nativeBuffer == NULL) ||
3035 (params->nativeBuffer->handle == NULL) ||
3036 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003037 return OMX_ErrorBadParameter;
3038 m_use_android_native_buffers = OMX_TRUE;
3039 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3040 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07003041 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 -07003042 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07003043 if (!secure_mode) {
3044 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003045 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07003046 if (buffer == MAP_FAILED) {
3047 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3048 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003049 }
3050 }
3051 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3052 } else {
3053 eRet = OMX_ErrorBadParameter;
3054 }
3055 return eRet;
3056}
3057#endif
Praveen Chavancf924182013-12-06 23:16:23 -08003058
3059OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
3060 struct v4l2_control control;
3061 struct v4l2_format fmt;
3062 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3063 control.value = 1;
3064 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3065 if (rc < 0) {
3066 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3067 return OMX_ErrorHardware;
3068 }
3069 m_smoothstreaming_mode = true;
3070 return OMX_ErrorNone;
3071}
3072
Shalaj Jain273b3e02012-06-22 19:08:03 -07003073/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003074 FUNCTION
3075 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07003076
Arun Menon906de572013-06-18 17:01:40 -07003077 DESCRIPTION
3078 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003079
Arun Menon906de572013-06-18 17:01:40 -07003080 PARAMETERS
3081 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003082
Arun Menon906de572013-06-18 17:01:40 -07003083 RETURN VALUE
3084 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003085
Arun Menon906de572013-06-18 17:01:40 -07003086 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003087OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003088 OMX_IN OMX_INDEXTYPE paramIndex,
3089 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003090{
3091 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003092 int ret=0;
3093 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07003094 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003095 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003096 return OMX_ErrorInvalidState;
3097 }
Arun Menon906de572013-06-18 17:01:40 -07003098 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003099 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07003100 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003101 }
Arun Menon906de572013-06-18 17:01:40 -07003102 if ((m_state != OMX_StateLoaded) &&
3103 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3104 (m_out_bEnabled == OMX_TRUE) &&
3105 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3106 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003107 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003108 return OMX_ErrorIncorrectStateOperation;
3109 }
Arun Menon906de572013-06-18 17:01:40 -07003110 switch ((unsigned long)paramIndex) {
3111 case OMX_IndexParamPortDefinition: {
3112 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3113 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3114 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3115 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003116 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07003117 (int)portDefn->format.video.nFrameHeight,
3118 (int)portDefn->format.video.nFrameWidth);
3119 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003120 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Pushkaraj Patil41588352014-02-25 20:51:34 +05303121 bool port_format_changed = false;
Arun Menon906de572013-06-18 17:01:40 -07003122 m_display_id = portDefn->format.video.pNativeWindow;
3123 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08003124 /* update output port resolution with client supplied dimensions
3125 in case scaling is enabled, else it follows input resolution set
3126 */
3127 if (is_down_scalar_enabled) {
3128 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003129 portDefn->format.video.nFrameWidth,
3130 portDefn->format.video.nFrameHeight);
3131 if (portDefn->format.video.nFrameHeight != 0x0 &&
3132 portDefn->format.video.nFrameWidth != 0x0) {
Pushkaraj Patil41588352014-02-25 20:51:34 +05303133 memset(&fmt, 0x0, sizeof(struct v4l2_format));
3134 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3135 fmt.fmt.pix_mp.pixelformat = capture_capability;
3136 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
3137 if (ret) {
3138 DEBUG_PRINT_ERROR("Get Resolution failed");
3139 eRet = OMX_ErrorHardware;
3140 break;
3141 }
3142 if ((portDefn->format.video.nFrameHeight != (int)fmt.fmt.pix_mp.height) ||
3143 (portDefn->format.video.nFrameWidth != (int)fmt.fmt.pix_mp.width)) {
3144 port_format_changed = true;
3145 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003146 update_resolution(portDefn->format.video.nFrameWidth,
3147 portDefn->format.video.nFrameHeight,
3148 portDefn->format.video.nFrameWidth,
3149 portDefn->format.video.nFrameHeight);
Pushkaraj Patil41588352014-02-25 20:51:34 +05303150
3151 /* set crop info */
3152 rectangle.nLeft = 0;
3153 rectangle.nTop = 0;
3154 rectangle.nWidth = portDefn->format.video.nFrameWidth;
3155 rectangle.nHeight = portDefn->format.video.nFrameHeight;
3156
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003157 eRet = is_video_session_supported();
3158 if (eRet)
3159 break;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303160 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003161 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3162 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3163 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3164 fmt.fmt.pix_mp.pixelformat = capture_capability;
3165 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);
3166 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3167 if (ret) {
3168 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3169 eRet = OMX_ErrorUnsupportedSetting;
3170 } else
3171 eRet = get_buffer_req(&drv_ctx.op_buf);
3172 }
Praveen Chavane78460c2013-12-06 23:16:04 -08003173 }
Arun Menon906de572013-06-18 17:01:40 -07003174 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003175 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07003176 eRet = OMX_ErrorBadParameter;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303177 } else if (!port_format_changed) {
Arun Menon906de572013-06-18 17:01:40 -07003178 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3179 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
3180 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3181 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3182 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
3183 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
3184 drv_ctx.extradata_info.buffer_size;
3185 eRet = set_buffer_req(&drv_ctx.op_buf);
3186 if (eRet == OMX_ErrorNone)
3187 m_port_def = *portDefn;
3188 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003189 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003190 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3191 portDefn->nBufferCountActual, portDefn->nBufferSize);
3192 eRet = OMX_ErrorBadParameter;
3193 }
3194 }
3195 } else if (OMX_DirInput == portDefn->eDir) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003196 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003197 bool port_format_changed = false;
3198 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
3199 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
3200 // Frame rate only should be set if this is a "known value" or to
3201 // activate ts prediction logic (arbitrary mode only) sending input
3202 // timestamps with max value (LLONG_MAX).
3203 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
3204 portDefn->format.video.xFramerate >> 16);
3205 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3206 drv_ctx.frame_rate.fps_denominator);
3207 if (!drv_ctx.frame_rate.fps_numerator) {
3208 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3209 drv_ctx.frame_rate.fps_numerator = 30;
3210 }
3211 if (drv_ctx.frame_rate.fps_denominator)
3212 drv_ctx.frame_rate.fps_numerator = (int)
3213 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3214 drv_ctx.frame_rate.fps_denominator = 1;
3215 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3216 drv_ctx.frame_rate.fps_numerator;
3217 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3218 frm_int, drv_ctx.frame_rate.fps_numerator /
3219 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003220
3221 struct v4l2_outputparm oparm;
3222 /*XXX: we're providing timing info as seconds per frame rather than frames
3223 * per second.*/
3224 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3225 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3226
3227 struct v4l2_streamparm sparm;
3228 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3229 sparm.parm.output = oparm;
3230 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3231 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
3232 eRet = OMX_ErrorHardware;
3233 break;
3234 }
Arun Menon906de572013-06-18 17:01:40 -07003235 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003236
Arun Menon906de572013-06-18 17:01:40 -07003237 if (drv_ctx.video_resolution.frame_height !=
3238 portDefn->format.video.nFrameHeight ||
3239 drv_ctx.video_resolution.frame_width !=
3240 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003241 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003242 portDefn->format.video.nFrameWidth,
3243 portDefn->format.video.nFrameHeight);
3244 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003245 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3246 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3247 if (frameHeight != 0x0 && frameWidth != 0x0) {
3248 if (m_smoothstreaming_mode &&
3249 ((frameWidth * frameHeight) <
3250 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3251 frameWidth = m_smoothstreaming_width;
3252 frameHeight = m_smoothstreaming_height;
3253 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3254 frameWidth, frameHeight);
3255 }
3256 update_resolution(frameWidth, frameHeight,
3257 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003258 eRet = is_video_session_supported();
3259 if (eRet)
3260 break;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303261 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Arun Menon906de572013-06-18 17:01:40 -07003262 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3263 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3264 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3265 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003266 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 -07003267 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3268 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003269 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003270 eRet = OMX_ErrorUnsupportedSetting;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303271 } else {
3272 if (!is_down_scalar_enabled)
3273 eRet = get_buffer_req(&drv_ctx.op_buf);
3274 }
Arun Menon906de572013-06-18 17:01:40 -07003275 }
3276 }
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +05303277 if (m_custom_buffersize.input_buffersize
3278 && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
3279 DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
3280 m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
3281 eRet = OMX_ErrorBadParameter;
3282 break;
3283 }
Arun Menon906de572013-06-18 17:01:40 -07003284 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3285 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3286 port_format_changed = true;
3287 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3288 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3289 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3290 (~(buffer_prop->alignment - 1));
3291 eRet = set_buffer_req(buffer_prop);
3292 }
3293 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003294 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003295 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3296 portDefn->nBufferCountActual, portDefn->nBufferSize);
3297 eRet = OMX_ErrorBadParameter;
3298 }
3299 } else if (portDefn->eDir == OMX_DirMax) {
3300 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3301 (int)portDefn->nPortIndex);
3302 eRet = OMX_ErrorBadPortIndex;
3303 }
3304 }
3305 break;
3306 case OMX_IndexParamVideoPortFormat: {
3307 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3308 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3309 int ret=0;
3310 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003311 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003312 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003313
Arun Menon906de572013-06-18 17:01:40 -07003314 if (1 == portFmt->nPortIndex) {
3315 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3316 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3317 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3318 fmt.fmt.pix_mp.pixelformat = capture_capability;
3319 enum vdec_output_fromat op_format;
3320 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3321 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Praveen Chavandb7776f2014-02-06 18:17:25 -08003322 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
3323 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar))
Arun Menon906de572013-06-18 17:01:40 -07003324 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Arun Menon906de572013-06-18 17:01:40 -07003325 else
3326 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003327
Arun Menon906de572013-06-18 17:01:40 -07003328 if (eRet == OMX_ErrorNone) {
3329 drv_ctx.output_format = op_format;
3330 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3331 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003332 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003333 eRet = OMX_ErrorUnsupportedSetting;
3334 /*TODO: How to handle this case */
3335 } else {
3336 eRet = get_buffer_req(&drv_ctx.op_buf);
3337 }
3338 }
3339 if (eRet == OMX_ErrorNone) {
3340 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003341 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003342 eRet = OMX_ErrorBadParameter;
3343 }
3344 }
3345 }
3346 }
3347 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003348
Arun Menon906de572013-06-18 17:01:40 -07003349 case OMX_QcomIndexPortDefn: {
3350 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3351 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003352 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003353 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003354
Arun Menon906de572013-06-18 17:01:40 -07003355 /* Input port */
3356 if (portFmt->nPortIndex == 0) {
3357 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3358 if (secure_mode) {
3359 arbitrary_bytes = false;
3360 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3361 eRet = OMX_ErrorUnsupportedSetting;
3362 } else {
3363 arbitrary_bytes = true;
3364 }
3365 } else if (portFmt->nFramePackingFormat ==
3366 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3367 arbitrary_bytes = false;
3368 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003369 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003370 portFmt->nFramePackingFormat);
3371 eRet = OMX_ErrorUnsupportedSetting;
3372 }
3373 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003374 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003375 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3376 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3377 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3378 m_out_mem_region_smi = OMX_TRUE;
3379 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003380 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003381 m_use_output_pmem = OMX_TRUE;
3382 }
3383 }
3384 }
3385 }
3386 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003387
Arun Menon906de572013-06-18 17:01:40 -07003388 case OMX_IndexParamStandardComponentRole: {
3389 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3390 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003391 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003392 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003393
Arun Menon906de572013-06-18 17:01:40 -07003394 if ((m_state == OMX_StateLoaded)&&
3395 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3396 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3397 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003398 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003399 return OMX_ErrorIncorrectStateOperation;
3400 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003401
Arun Menon906de572013-06-18 17:01:40 -07003402 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3403 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3404 strlcpy((char*)m_cRole,"video_decoder.avc",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.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3410 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3411 strlcpy((char*)m_cRole,"video_decoder.mpeg4",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.h263",OMX_MAX_STRINGNAME_SIZE)) {
3417 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3418 strlcpy((char*)m_cRole,"video_decoder.h263",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.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3424 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3425 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3426 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003427 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003428 eRet = OMX_ErrorUnsupportedSetting;
3429 }
3430 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
Deva Ramasubramanianba4534b2013-12-17 15:52:37 -08003431 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) ||
3432 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE))
Arun Menon906de572013-06-18 17:01:40 -07003433 ) {
3434 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3435 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3436 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003437 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003438 eRet =OMX_ErrorUnsupportedSetting;
3439 }
3440 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3441 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3442 ) {
3443 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3444 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3445 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003446 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003447 eRet =OMX_ErrorUnsupportedSetting;
3448 }
3449 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3450 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3451 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3452 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3453 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003454 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003455 eRet = OMX_ErrorUnsupportedSetting;
3456 }
3457 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003458 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003459 eRet = OMX_ErrorInvalidComponentName;
3460 }
3461 break;
3462 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003463
Arun Menon906de572013-06-18 17:01:40 -07003464 case OMX_IndexParamPriorityMgmt: {
3465 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003466 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003467 return OMX_ErrorIncorrectStateOperation;
3468 }
3469 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003470 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003471 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003472
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003473 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003474 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003475
Arun Menon906de572013-06-18 17:01:40 -07003476 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3477 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003478
Arun Menon906de572013-06-18 17:01:40 -07003479 break;
3480 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003481
Arun Menon906de572013-06-18 17:01:40 -07003482 case OMX_IndexParamCompBufferSupplier: {
3483 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003484 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003485 bufferSupplierType->eBufferSupplier);
3486 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3487 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003488
Arun Menon906de572013-06-18 17:01:40 -07003489 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003490
Arun Menon906de572013-06-18 17:01:40 -07003491 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003492
Arun Menon906de572013-06-18 17:01:40 -07003493 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003494
Arun Menon906de572013-06-18 17:01:40 -07003495 }
3496 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003497 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003498 paramIndex);
3499 break;
3500 }
3501 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003502 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003503 paramIndex);
3504 break;
3505 }
3506 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003507 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003508 paramIndex);
3509 break;
3510 }
3511 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003512 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003513 paramIndex);
3514 break;
3515 }
3516 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3517 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3518 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3519 struct v4l2_control control;
3520 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003521 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003522 pictureOrder->eOutputPictureOrder);
3523 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3524 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3525 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3526 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3527 time_stamp_dts.set_timestamp_reorder_mode(false);
3528 } else
3529 eRet = OMX_ErrorBadParameter;
3530 if (eRet == OMX_ErrorNone) {
3531 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3532 control.value = pic_order;
3533 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3534 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003535 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003536 eRet = OMX_ErrorUnsupportedSetting;
3537 }
3538 }
3539 break;
3540 }
3541 case OMX_QcomIndexParamConcealMBMapExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303542 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3543 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3544 break;
3545 case OMX_QcomIndexParamFrameInfoExtraData:
3546 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3547 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3548 break;
Arun Menon906de572013-06-18 17:01:40 -07003549 case OMX_QcomIndexParamInterlaceExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303550 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3551 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3552 break;
Arun Menon906de572013-06-18 17:01:40 -07003553 case OMX_QcomIndexParamH264TimeInfo:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303554 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3555 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3556 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303557 case OMX_QcomIndexParamVideoFramePackingExtradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303558 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3559 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3560 break;
3561 case OMX_QcomIndexParamVideoQPExtraData:
3562 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
3563 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3564 break;
3565 case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
3566 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
3567 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3568 break;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05303569 case OMX_QcomIndexEnableExtnUserData:
3570 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
3571 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3572 break;
Arun Menon906de572013-06-18 17:01:40 -07003573 case OMX_QcomIndexParamVideoDivx: {
3574 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3575 }
3576 break;
3577 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003578 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003579 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3580 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3581 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3582 eRet = OMX_ErrorUnsupportedSetting;
3583 } else {
3584 m_out_pvt_entry_pmem = OMX_TRUE;
3585 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003586 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003587 m_use_output_pmem = OMX_TRUE;
3588 }
3589 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003590
Arun Menon906de572013-06-18 17:01:40 -07003591 }
3592 break;
3593 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3594 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3595 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3596 struct v4l2_control control;
3597 int rc;
3598 drv_ctx.idr_only_decoding = 1;
3599 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3600 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
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("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003604 eRet = OMX_ErrorUnsupportedSetting;
3605 } else {
3606 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3607 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3608 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3609 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003610 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003611 eRet = OMX_ErrorUnsupportedSetting;
3612 }
3613 /*Setting sync frame decoding on driver might change buffer
3614 * requirements so update them here*/
3615 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003616 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003617 eRet = OMX_ErrorUnsupportedSetting;
3618 }
3619 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003620 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003621 eRet = OMX_ErrorUnsupportedSetting;
3622 }
3623 }
3624 }
3625 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003626
Arun Menon906de572013-06-18 17:01:40 -07003627 case OMX_QcomIndexParamIndexExtraDataType: {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303628 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3629 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3630 (extradataIndexType->bEnabled == OMX_TRUE) &&
3631 (extradataIndexType->nPortIndex == 1)) {
3632 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
3633 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
3634 }
3635 }
Arun Menon906de572013-06-18 17:01:40 -07003636 break;
3637 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003638#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003639 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003640#else
Arun Menon906de572013-06-18 17:01:40 -07003641 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003642#endif
Arun Menon906de572013-06-18 17:01:40 -07003643 }
3644 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003645#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003646 /* Need to allow following two set_parameters even in Idle
3647 * state. This is ANDROID architecture which is not in sync
3648 * with openmax standard. */
3649 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3650 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3651 if (enableNativeBuffers) {
3652 m_enable_android_native_buffers = enableNativeBuffers->enable;
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07003653 }
Praveen Chavancac86402014-10-18 09:14:52 -07003654#if !defined(FLEXYUV_SUPPORTED)
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07003655 if (m_enable_android_native_buffers) {
3656 // Use the most-preferred-native-color-format as surface-mode is hinted here
3657 if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
3658 DEBUG_PRINT_ERROR("Failed to set native color format!");
3659 eRet = OMX_ErrorUnsupportedSetting;
3660 }
Arun Menon906de572013-06-18 17:01:40 -07003661 }
Praveen Chavancac86402014-10-18 09:14:52 -07003662#endif
Arun Menon906de572013-06-18 17:01:40 -07003663 }
3664 break;
3665 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3666 eRet = use_android_native_buffer(hComp, paramData);
3667 }
3668 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003669#endif
Arun Menon906de572013-06-18 17:01:40 -07003670 case OMX_QcomIndexParamEnableTimeStampReorder: {
3671 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3672 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3673 if (reorder->bEnable == OMX_TRUE) {
3674 frm_int =0;
3675 time_stamp_dts.set_timestamp_reorder_mode(true);
3676 } else
3677 time_stamp_dts.set_timestamp_reorder_mode(false);
3678 } else {
3679 time_stamp_dts.set_timestamp_reorder_mode(false);
3680 if (reorder->bEnable == OMX_TRUE) {
3681 eRet = OMX_ErrorUnsupportedSetting;
3682 }
3683 }
3684 }
3685 break;
3686 case OMX_IndexParamVideoProfileLevelCurrent: {
3687 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3688 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3689 if (pParam) {
3690 m_profile_lvl.eProfile = pParam->eProfile;
3691 m_profile_lvl.eLevel = pParam->eLevel;
3692 }
3693 break;
Arun Menon888aa852013-05-30 11:24:42 -07003694
Arun Menon906de572013-06-18 17:01:40 -07003695 }
Arun Menone5652482013-08-04 13:33:05 -07003696 case OMX_QcomIndexParamVideoMetaBufferMode:
3697 {
3698 StoreMetaDataInBuffersParams *metabuffer =
3699 (StoreMetaDataInBuffersParams *)paramData;
3700 if (!metabuffer) {
3701 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3702 eRet = OMX_ErrorBadParameter;
3703 break;
3704 }
3705 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3706 //set property dynamic buffer mode to driver.
3707 struct v4l2_control control;
3708 struct v4l2_format fmt;
3709 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3710 if (metabuffer->bStoreMetaData == true) {
3711 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3712 } else {
3713 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3714 }
3715 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3716 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003717 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003718 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003719 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003720 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003721 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003722 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3723 eRet = OMX_ErrorUnsupportedSetting;
3724 }
3725 } else {
3726 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003727 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003728 metabuffer->nPortIndex);
3729 eRet = OMX_ErrorUnsupportedSetting;
3730 }
3731 break;
3732 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003733 case OMX_QcomIndexParamVideoDownScalar: {
3734 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3735 struct v4l2_control control;
3736 int rc;
3737 if (pParam) {
3738 is_down_scalar_enabled = pParam->bEnable;
3739 if (is_down_scalar_enabled) {
3740 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3741 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3742 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3743 pParam->bEnable);
3744 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3745 if (rc < 0) {
3746 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3747 eRet = OMX_ErrorUnsupportedSetting;
3748 }
3749 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3750 control.value = 1;
3751 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3752 if (rc < 0) {
3753 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3754 eRet = OMX_ErrorUnsupportedSetting;
3755 }
3756 }
3757 }
3758 break;
3759 }
Praveen Chavancf924182013-12-06 23:16:23 -08003760#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3761 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3762 {
3763 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3764 PrepareForAdaptivePlaybackParams* pParams =
3765 (PrepareForAdaptivePlaybackParams *) paramData;
3766 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3767 if (!pParams->bEnable) {
3768 return OMX_ErrorNone;
3769 }
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303770 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
3771 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
Praveen Chavancf924182013-12-06 23:16:23 -08003772 DEBUG_PRINT_ERROR(
3773 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3774 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303775 maxSmoothStreamingWidth, maxSmoothStreamingHeight);
Praveen Chavancf924182013-12-06 23:16:23 -08003776 eRet = OMX_ErrorBadParameter;
3777 } else {
Arun Menon1fc764f2014-04-17 15:41:27 -07003778 eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3779 }
Praveen Chavancf924182013-12-06 23:16:23 -08003780 } else {
3781 DEBUG_PRINT_ERROR(
3782 "Prepare for adaptive playback supported only on output port");
3783 eRet = OMX_ErrorBadParameter;
3784 }
3785 break;
3786 }
3787
3788#endif
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +05303789 case OMX_QcomIndexParamVideoCustomBufferSize:
3790 {
3791 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
3792 QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
3793 if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3794 struct v4l2_control control;
3795 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
3796 control.value = pParam->nBufferSize;
3797 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
3798 DEBUG_PRINT_ERROR("Failed to set input buffer size");
3799 eRet = OMX_ErrorUnsupportedSetting;
3800 } else {
3801 eRet = get_buffer_req(&drv_ctx.ip_buf);
3802 if (eRet == OMX_ErrorNone) {
3803 m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
3804 DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
3805 m_custom_buffersize.input_buffersize);
3806 } else {
3807 DEBUG_PRINT_ERROR("Failed to get buffer requirement");
3808 }
3809 }
3810 } else {
3811 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
3812 eRet = OMX_ErrorBadParameter;
3813 }
3814 break;
3815 }
Arun Menon906de572013-06-18 17:01:40 -07003816 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003817 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003818 eRet = OMX_ErrorUnsupportedIndex;
3819 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003820 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003821 if (eRet != OMX_ErrorNone)
3822 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003823 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003824}
3825
3826/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003827 FUNCTION
3828 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003829
Arun Menon906de572013-06-18 17:01:40 -07003830 DESCRIPTION
3831 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003832
Arun Menon906de572013-06-18 17:01:40 -07003833 PARAMETERS
3834 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003835
Arun Menon906de572013-06-18 17:01:40 -07003836 RETURN VALUE
3837 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003838
Arun Menon906de572013-06-18 17:01:40 -07003839 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003840OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003841 OMX_IN OMX_INDEXTYPE configIndex,
3842 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003843{
Arun Menon906de572013-06-18 17:01:40 -07003844 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003845
Arun Menon906de572013-06-18 17:01:40 -07003846 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003847 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003848 return OMX_ErrorInvalidState;
3849 }
Arun Menon906de572013-06-18 17:01:40 -07003850
3851 switch ((unsigned long)configIndex) {
3852 case OMX_QcomIndexConfigInterlaced: {
3853 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3854 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3855 if (configFmt->nPortIndex == 1) {
3856 if (configFmt->nIndex == 0) {
3857 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3858 } else if (configFmt->nIndex == 1) {
3859 configFmt->eInterlaceType =
3860 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3861 } else if (configFmt->nIndex == 2) {
3862 configFmt->eInterlaceType =
3863 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3864 } else {
3865 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003866 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003867 eRet = OMX_ErrorNoMore;
3868 }
3869
3870 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003871 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003872 (int)configFmt->nPortIndex);
3873 eRet = OMX_ErrorBadPortIndex;
3874 }
3875 break;
3876 }
3877 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3878 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3879 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3880 decoderinstances->nNumOfInstances = 16;
3881 /*TODO: How to handle this case */
3882 break;
3883 }
3884 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3885 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3886 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3887 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303888 memcpy(configFmt, &m_frame_pack_arrangement,
3889 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003890 } else {
3891 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3892 }
3893 break;
3894 }
3895 case OMX_IndexConfigCommonOutputCrop: {
3896 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3897 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05303898 DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
3899 rectangle.nLeft, rectangle.nTop,
3900 rectangle.nWidth, rectangle.nHeight);
Arun Menon906de572013-06-18 17:01:40 -07003901 break;
3902 }
3903 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003904 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003905 eRet = OMX_ErrorBadParameter;
3906 }
3907
Shalaj Jain273b3e02012-06-22 19:08:03 -07003908 }
Arun Menon906de572013-06-18 17:01:40 -07003909
3910 return eRet;
3911}
3912
3913/* ======================================================================
3914 FUNCTION
3915 omx_vdec::SetConfig
3916
3917 DESCRIPTION
3918 OMX Set Config method implementation
3919
3920 PARAMETERS
3921 <TBD>.
3922
3923 RETURN VALUE
3924 OMX Error None if successful.
3925 ========================================================================== */
3926OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3927 OMX_IN OMX_INDEXTYPE configIndex,
3928 OMX_IN OMX_PTR configData)
3929{
3930 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003931 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003932 return OMX_ErrorInvalidState;
3933 }
3934
3935 OMX_ERRORTYPE ret = OMX_ErrorNone;
3936 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3937
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003938 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003939
3940 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3941 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003942 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003943 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003944 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003945 OMX_U32 extra_size;
3946 // Parsing done here for the AVC atom is definitely not generic
3947 // Currently this piece of code is working, but certainly
3948 // not tested with all .mp4 files.
3949 // Incase of failure, we might need to revisit this
3950 // for a generic piece of code.
3951
3952 // Retrieve size of NAL length field
3953 // byte #4 contains the size of NAL lenght field
3954 nal_length = (config->pData[4] & 0x03) + 1;
3955
3956 extra_size = 0;
3957 if (nal_length > 2) {
3958 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3959 extra_size = (nal_length - 2) * 2;
3960 }
3961
3962 // SPS starts from byte #6
3963 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3964 OMX_U8 *pDestBuf;
3965 m_vendor_config.nPortIndex = config->nPortIndex;
3966
3967 // minus 6 --> SPS starts from byte #6
3968 // minus 1 --> picture param set byte to be ignored from avcatom
3969 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3970 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3971 OMX_U32 len;
3972 OMX_U8 index = 0;
3973 // case where SPS+PPS is sent as part of set_config
3974 pDestBuf = m_vendor_config.pData;
3975
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003976 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003977 m_vendor_config.nPortIndex,
3978 m_vendor_config.nDataSize,
3979 m_vendor_config.pData);
3980 while (index < 2) {
3981 uint8 *psize;
3982 len = *pSrcBuf;
3983 len = len << 8;
3984 len |= *(pSrcBuf + 1);
3985 psize = (uint8 *) & len;
3986 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3987 for (unsigned int i = 0; i < nal_length; i++) {
3988 pDestBuf[i] = psize[nal_length - 1 - i];
3989 }
3990 //memcpy(pDestBuf,pSrcBuf,(len+2));
3991 pDestBuf += len + nal_length;
3992 pSrcBuf += len + 2;
3993 index++;
3994 pSrcBuf++; // skip picture param set
3995 len = 0;
3996 }
3997 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3998 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3999 m_vendor_config.nPortIndex = config->nPortIndex;
4000 m_vendor_config.nDataSize = config->nDataSize;
4001 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
4002 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
4003 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
4004 if (m_vendor_config.pData) {
4005 free(m_vendor_config.pData);
4006 m_vendor_config.pData = NULL;
4007 m_vendor_config.nDataSize = 0;
4008 }
4009
4010 if (((*((OMX_U32 *) config->pData)) &
4011 VC1_SP_MP_START_CODE_MASK) ==
4012 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004013 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07004014 m_vendor_config.nPortIndex = config->nPortIndex;
4015 m_vendor_config.nDataSize = config->nDataSize;
4016 m_vendor_config.pData =
4017 (OMX_U8 *) malloc(config->nDataSize);
4018 memcpy(m_vendor_config.pData, config->pData,
4019 config->nDataSize);
4020 m_vc1_profile = VC1_SP_MP_RCV;
4021 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004022 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07004023 m_vendor_config.nPortIndex = config->nPortIndex;
4024 m_vendor_config.nDataSize = config->nDataSize;
4025 m_vendor_config.pData =
4026 (OMX_U8 *) malloc((config->nDataSize));
4027 memcpy(m_vendor_config.pData, config->pData,
4028 config->nDataSize);
4029 m_vc1_profile = VC1_AP;
4030 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004031 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07004032 m_vendor_config.nPortIndex = config->nPortIndex;
4033 m_vendor_config.nDataSize = config->nDataSize;
4034 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
4035 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
4036 m_vc1_profile = VC1_SP_MP_RCV;
4037 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004038 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07004039 }
4040 }
4041 return ret;
4042 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
4043 struct v4l2_control temp;
4044 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
4045
4046 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
4047 switch (pNal->nNaluBytes) {
4048 case 0:
4049 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
4050 break;
4051 case 2:
4052 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
4053 break;
4054 case 4:
4055 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
4056 break;
4057 default:
4058 return OMX_ErrorUnsupportedSetting;
4059 }
4060
4061 if (!arbitrary_bytes) {
4062 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
4063 * with start code, so only need to notify driver in frame by frame mode */
4064 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
4065 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
4066 return OMX_ErrorHardware;
4067 }
4068 }
4069
4070 nal_length = pNal->nNaluBytes;
4071 m_frame_parser.init_nal_length(nal_length);
4072
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004073 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07004074 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05304075 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07004076 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05304077 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07004078
4079 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
4080 if (config->bEnabled) {
4081 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05304082 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07004083 config->nFps >> 16);
4084 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
4085 drv_ctx.frame_rate.fps_denominator);
4086
4087 if (!drv_ctx.frame_rate.fps_numerator) {
4088 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
4089 drv_ctx.frame_rate.fps_numerator = 30;
4090 }
4091
4092 if (drv_ctx.frame_rate.fps_denominator) {
4093 drv_ctx.frame_rate.fps_numerator = (int)
4094 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
4095 }
4096
4097 drv_ctx.frame_rate.fps_denominator = 1;
4098 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
4099 drv_ctx.frame_rate.fps_numerator;
4100
4101 struct v4l2_outputparm oparm;
4102 /*XXX: we're providing timing info as seconds per frame rather than frames
4103 * per second.*/
4104 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
4105 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
4106
4107 struct v4l2_streamparm sparm;
4108 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4109 sparm.parm.output = oparm;
4110 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
4111 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
4112 performance might be affected");
4113 ret = OMX_ErrorHardware;
4114 }
4115 client_set_fps = true;
4116 } else {
4117 DEBUG_PRINT_ERROR("Frame rate not supported.");
4118 ret = OMX_ErrorUnsupportedSetting;
4119 }
4120 } else {
4121 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
4122 client_set_fps = false;
4123 }
4124 } else {
4125 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
4126 (int)config->nPortIndex);
4127 ret = OMX_ErrorBadPortIndex;
4128 }
4129
4130 return ret;
Praveen Chavan898df262015-04-20 18:52:19 -07004131 } else if ((int)configIndex == (int)OMX_IndexConfigPriority) {
4132 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
4133 DEBUG_PRINT_LOW("Set_config: priority %d", priority->nU32);
4134
4135 struct v4l2_control control;
4136
4137 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
4138 if (priority->nU32 == 0)
4139 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
4140 else
4141 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
4142
4143 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
4144 DEBUG_PRINT_ERROR("Failed to set Priority");
4145 ret = OMX_ErrorUnsupportedSetting;
4146 }
4147 return ret;
Arun Menon906de572013-06-18 17:01:40 -07004148 }
4149
4150 return OMX_ErrorNotImplemented;
4151}
4152
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304153#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
4154
Arun Menon906de572013-06-18 17:01:40 -07004155/* ======================================================================
4156 FUNCTION
4157 omx_vdec::GetExtensionIndex
4158
4159 DESCRIPTION
4160 OMX GetExtensionIndex method implementaion. <TBD>
4161
4162 PARAMETERS
4163 <TBD>.
4164
4165 RETURN VALUE
4166 OMX Error None if everything successful.
4167
4168 ========================================================================== */
4169OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
4170 OMX_IN OMX_STRING paramName,
4171 OMX_OUT OMX_INDEXTYPE* indexType)
4172{
4173 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004174 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004175 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304176 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07004177 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304178 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004179 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304180 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
4181 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
4182 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
4183 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08004184 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
4185 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08004186 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
4187 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08004188 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
4189 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004190 }
4191#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304192 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004193 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304194 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004195 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304196 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004197 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004198 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304199 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004200 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4201 }
4202#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304203 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07004204 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
4205 }
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05304206#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Praveen Chavancf924182013-12-06 23:16:23 -08004207 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
4208 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
4209 }
4210#endif
Praveen Chavan09a82b72014-10-18 09:09:45 -07004211#ifdef FLEXYUV_SUPPORTED
4212 else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
4213 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
4214 }
4215#endif
Arun Menon906de572013-06-18 17:01:40 -07004216 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004217 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004218 return OMX_ErrorNotImplemented;
4219 }
4220 return OMX_ErrorNone;
4221}
4222
4223/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004224 FUNCTION
4225 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07004226
Arun Menon906de572013-06-18 17:01:40 -07004227 DESCRIPTION
4228 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004229
Arun Menon906de572013-06-18 17:01:40 -07004230 PARAMETERS
4231 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004232
Arun Menon906de572013-06-18 17:01:40 -07004233 RETURN VALUE
4234 Error None if everything is successful.
4235 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004236OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004237 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004238{
Arun Menon906de572013-06-18 17:01:40 -07004239 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004240 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07004241 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004242}
4243
4244/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004245 FUNCTION
4246 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07004247
Arun Menon906de572013-06-18 17:01:40 -07004248 DESCRIPTION
4249 OMX Component Tunnel Request method implementation. <TBD>
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 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004256
Arun Menon906de572013-06-18 17:01:40 -07004257 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004258OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004259 OMX_IN OMX_U32 port,
4260 OMX_IN OMX_HANDLETYPE peerComponent,
4261 OMX_IN OMX_U32 peerPort,
4262 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004263{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004264 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07004265 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004266}
4267
4268/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004269 FUNCTION
4270 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004271
Arun Menon906de572013-06-18 17:01:40 -07004272 DESCRIPTION
4273 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004274
Arun Menon906de572013-06-18 17:01:40 -07004275 PARAMETERS
4276 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004277
Arun Menon906de572013-06-18 17:01:40 -07004278 RETURN VALUE
4279 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004280
Arun Menon906de572013-06-18 17:01:40 -07004281 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004282OMX_ERRORTYPE omx_vdec::allocate_extradata()
4283{
4284#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004285 if (drv_ctx.extradata_info.buffer_size) {
4286 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4287 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4288 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4289 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004290 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004291 }
4292 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4293 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4294 drv_ctx.extradata_info.size, 4096,
4295 &drv_ctx.extradata_info.ion.ion_alloc_data,
4296 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4297 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004298 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004299 return OMX_ErrorInsufficientResources;
4300 }
4301 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4302 drv_ctx.extradata_info.size,
4303 PROT_READ|PROT_WRITE, MAP_SHARED,
4304 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4305 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004306 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004307 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4308 free_ion_memory(&drv_ctx.extradata_info.ion);
4309 return OMX_ErrorInsufficientResources;
4310 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004311 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004312#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304313 if (!m_other_extradata) {
4314 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4315 if (!m_other_extradata) {
4316 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4317 return OMX_ErrorInsufficientResources;
4318 }
4319 }
Arun Menon906de572013-06-18 17:01:40 -07004320 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004321}
4322
Arun Menon906de572013-06-18 17:01:40 -07004323void omx_vdec::free_extradata()
4324{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004325#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004326 if (drv_ctx.extradata_info.uaddr) {
4327 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4328 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4329 free_ion_memory(&drv_ctx.extradata_info.ion);
4330 }
4331 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004332#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304333 if (m_other_extradata) {
4334 free(m_other_extradata);
4335 m_other_extradata = NULL;
4336 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004337}
4338
Shalaj Jain273b3e02012-06-22 19:08:03 -07004339OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004340 OMX_IN OMX_HANDLETYPE hComp,
4341 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4342 OMX_IN OMX_U32 port,
4343 OMX_IN OMX_PTR appData,
4344 OMX_IN OMX_U32 bytes,
4345 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004346{
Arun Menon906de572013-06-18 17:01:40 -07004347 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4348 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4349 unsigned i= 0; // Temporary counter
4350 struct vdec_setbuffer_cmd setbuffers;
4351 OMX_PTR privateAppData = NULL;
4352 private_handle_t *handle = NULL;
4353 OMX_U8 *buff = buffer;
4354 struct v4l2_buffer buf;
4355 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4356 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004357
Arun Menon906de572013-06-18 17:01:40 -07004358 if (!m_out_mem_ptr) {
4359 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4360 eRet = allocate_output_headers();
4361 if (eRet == OMX_ErrorNone)
4362 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004363 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004364
Arun Menon906de572013-06-18 17:01:40 -07004365 if (eRet == OMX_ErrorNone) {
4366 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4367 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4368 break;
4369 }
4370 }
4371 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004372
Arun Menon906de572013-06-18 17:01:40 -07004373 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004374 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004375 eRet = OMX_ErrorInsufficientResources;
4376 }
4377
Arun Menonbdb80b02013-08-12 17:45:54 -07004378 if (dynamic_buf_mode) {
4379 *bufferHdr = (m_out_mem_ptr + i );
4380 (*bufferHdr)->pBuffer = NULL;
4381 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4382 enum v4l2_buf_type buf_type;
4383 int rr = 0;
4384 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4385 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4386 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4387 return OMX_ErrorInsufficientResources;
4388 } else {
4389 streaming[CAPTURE_PORT] = true;
4390 DEBUG_PRINT_LOW("STREAMON Successful");
4391 }
4392 }
4393 BITMASK_SET(&m_out_bm_count,i);
4394 (*bufferHdr)->pAppPrivate = appData;
4395 (*bufferHdr)->pBuffer = buffer;
4396 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4397 return eRet;
4398 }
Arun Menon906de572013-06-18 17:01:40 -07004399 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004400#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004401 if (m_enable_android_native_buffers) {
4402 if (m_use_android_native_buffers) {
4403 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4404 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4405 handle = (private_handle_t *)nBuf->handle;
4406 privateAppData = params->pAppPrivate;
4407 } else {
4408 handle = (private_handle_t *)buff;
4409 privateAppData = appData;
4410 }
Arun Menon8544ead2014-05-08 17:42:29 -07004411 if (!handle) {
4412 DEBUG_PRINT_ERROR("handle is invalid");
4413 return OMX_ErrorBadParameter;
4414 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004415
Arun Menon906de572013-06-18 17:01:40 -07004416 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4417 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4418 " expected %u, got %lu",
4419 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4420 return OMX_ErrorBadParameter;
4421 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004422
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07004423 drv_ctx.op_buf.buffer_size = handle->size;
4424
Arun Menon906de572013-06-18 17:01:40 -07004425 if (!m_use_android_native_buffers) {
4426 if (!secure_mode) {
4427 buff = (OMX_U8*)mmap(0, handle->size,
4428 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4429 if (buff == MAP_FAILED) {
4430 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4431 return OMX_ErrorInsufficientResources;
4432 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004433 }
4434 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004435#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004436 native_buffer[i].nativehandle = handle;
4437 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004438#endif
Arun Menon906de572013-06-18 17:01:40 -07004439 if (!handle) {
4440 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4441 return OMX_ErrorBadParameter;
4442 }
4443 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4444 drv_ctx.ptr_outputbuffer[i].offset = 0;
4445 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4446 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4447 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4448 } else
4449#endif
4450
4451 if (!ouput_egl_buffers && !m_use_output_pmem) {
4452#ifdef USE_ION
4453 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4454 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4455 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4456 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4457 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004458 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 -07004459 return OMX_ErrorInsufficientResources;
4460 }
4461 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4462 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4463#else
4464 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4465 open (MEM_DEVICE,O_RDWR);
4466
4467 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004468 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004469 return OMX_ErrorInsufficientResources;
4470 }
4471
4472 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4473 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4474 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4475 open (MEM_DEVICE,O_RDWR);
4476 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004477 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004478 return OMX_ErrorInsufficientResources;
4479 }
4480 }
4481
4482 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4483 drv_ctx.op_buf.buffer_size,
4484 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004485 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004486 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4487 return OMX_ErrorInsufficientResources;
4488 }
4489#endif
4490 if (!secure_mode) {
4491 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4492 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4493 PROT_READ|PROT_WRITE, MAP_SHARED,
4494 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4495 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4496 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4497#ifdef USE_ION
4498 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4499#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004500 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004501 return OMX_ErrorInsufficientResources;
4502 }
4503 }
4504 drv_ctx.ptr_outputbuffer[i].offset = 0;
4505 privateAppData = appData;
4506 } else {
4507
4508 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4509 if (!appData || !bytes ) {
4510 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004511 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004512 return OMX_ErrorBadParameter;
4513 }
4514 }
4515
4516 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4517 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4518 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
Arun Menon8544ead2014-05-08 17:42:29 -07004519 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
Arun Menon906de572013-06-18 17:01:40 -07004520 !pmem_list->nEntries ||
4521 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004522 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004523 return OMX_ErrorBadParameter;
4524 }
4525 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4526 pmem_list->entryList->entry;
4527 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4528 pmem_info->pmem_fd);
4529 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4530 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4531 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4532 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4533 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4534 privateAppData = appData;
4535 }
4536 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4537 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304538 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4539 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4540 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004541
4542 *bufferHdr = (m_out_mem_ptr + i );
4543 if (secure_mode)
4544 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4545 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4546 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4547 sizeof (vdec_bufferpayload));
4548
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004549 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004550 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4551 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4552
4553 buf.index = i;
4554 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4555 buf.memory = V4L2_MEMORY_USERPTR;
4556 plane[0].length = drv_ctx.op_buf.buffer_size;
4557 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4558 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4559 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4560 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4561 plane[0].data_offset = 0;
4562 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4563 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4564 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4565 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4566#ifdef USE_ION
4567 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4568#endif
4569 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4570 plane[extra_idx].data_offset = 0;
4571 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004572 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004573 return OMX_ErrorBadParameter;
4574 }
Arun Menon906de572013-06-18 17:01:40 -07004575 buf.m.planes = plane;
4576 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004577
Arun Menon906de572013-06-18 17:01:40 -07004578 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004579 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004580 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004581 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004582 }
4583
Arun Menon906de572013-06-18 17:01:40 -07004584 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4585 enum v4l2_buf_type buf_type;
4586 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4587 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4588 return OMX_ErrorInsufficientResources;
4589 } else {
4590 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004591 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004592 }
4593 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004594
Arun Menon906de572013-06-18 17:01:40 -07004595 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4596 if (m_enable_android_native_buffers) {
4597 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4598 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4599 } else {
4600 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004601 }
Arun Menon906de572013-06-18 17:01:40 -07004602 (*bufferHdr)->pAppPrivate = privateAppData;
4603 BITMASK_SET(&m_out_bm_count,i);
4604 }
4605 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004606}
4607
4608/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004609 FUNCTION
4610 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004611
Arun Menon906de572013-06-18 17:01:40 -07004612 DESCRIPTION
4613 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004614
Arun Menon906de572013-06-18 17:01:40 -07004615 PARAMETERS
4616 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004617
Arun Menon906de572013-06-18 17:01:40 -07004618 RETURN VALUE
4619 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004620
Arun Menon906de572013-06-18 17:01:40 -07004621 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004622OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004623 OMX_IN OMX_HANDLETYPE hComp,
4624 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4625 OMX_IN OMX_U32 port,
4626 OMX_IN OMX_PTR appData,
4627 OMX_IN OMX_U32 bytes,
4628 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004629{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004630 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004631 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4632 if (!m_inp_heap_ptr)
4633 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4634 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4635 drv_ctx.ip_buf.actualcount);
4636 if (!m_phdr_pmem_ptr)
4637 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4638 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4639 drv_ctx.ip_buf.actualcount);
4640 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4641 DEBUG_PRINT_ERROR("Insufficent memory");
4642 eRet = OMX_ErrorInsufficientResources;
4643 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4644 input_use_buffer = true;
4645 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4646 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4647 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4648 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4649 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4650 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4651 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4652 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004653 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 -07004654 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4655 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004656 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004657 return OMX_ErrorInsufficientResources;
4658 }
4659 m_in_alloc_cnt++;
4660 } else {
4661 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4662 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004663 }
Arun Menon906de572013-06-18 17:01:40 -07004664 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004665}
4666
4667/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004668 FUNCTION
4669 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004670
Arun Menon906de572013-06-18 17:01:40 -07004671 DESCRIPTION
4672 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004673
Arun Menon906de572013-06-18 17:01:40 -07004674 PARAMETERS
4675 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004676
Arun Menon906de572013-06-18 17:01:40 -07004677 RETURN VALUE
4678 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004679
Arun Menon906de572013-06-18 17:01:40 -07004680 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004681OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004682 OMX_IN OMX_HANDLETYPE hComp,
4683 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4684 OMX_IN OMX_U32 port,
4685 OMX_IN OMX_PTR appData,
4686 OMX_IN OMX_U32 bytes,
4687 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004688{
Arun Menon906de572013-06-18 17:01:40 -07004689 OMX_ERRORTYPE error = OMX_ErrorNone;
4690 struct vdec_setbuffer_cmd setbuffers;
4691
Arun Menon8544ead2014-05-08 17:42:29 -07004692 if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
4693 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4694 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004695 }
Arun Menon906de572013-06-18 17:01:40 -07004696 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004697 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004698 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004699 }
Arun Menon906de572013-06-18 17:01:40 -07004700 if (port == OMX_CORE_INPUT_PORT_INDEX)
4701 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4702 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4703 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4704 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004705 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004706 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004707 }
Arun Menon906de572013-06-18 17:01:40 -07004708 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4709 if (error == OMX_ErrorNone) {
4710 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4711 // Send the callback now
4712 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4713 post_event(OMX_CommandStateSet,OMX_StateIdle,
4714 OMX_COMPONENT_GENERATE_EVENT);
4715 }
4716 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4717 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4718 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4719 post_event(OMX_CommandPortEnable,
4720 OMX_CORE_INPUT_PORT_INDEX,
4721 OMX_COMPONENT_GENERATE_EVENT);
4722 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4723 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4724 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4725 post_event(OMX_CommandPortEnable,
4726 OMX_CORE_OUTPUT_PORT_INDEX,
4727 OMX_COMPONENT_GENERATE_EVENT);
4728 }
4729 }
4730 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004731}
4732
4733OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004734 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004735{
Arun Menon906de572013-06-18 17:01:40 -07004736 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4737 if (m_inp_heap_ptr[bufferindex].pBuffer)
4738 free(m_inp_heap_ptr[bufferindex].pBuffer);
4739 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4740 }
4741 if (pmem_bufferHdr)
4742 free_input_buffer(pmem_bufferHdr);
4743 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004744}
4745
4746OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4747{
Arun Menon906de572013-06-18 17:01:40 -07004748 unsigned int index = 0;
4749 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4750 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004751 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004752
Arun Menon906de572013-06-18 17:01:40 -07004753 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004754 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004755
4756 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004757 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004758 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4759 struct vdec_setbuffer_cmd setbuffers;
4760 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4761 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4762 sizeof (vdec_bufferpayload));
4763 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004764 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004765 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004766 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004767 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4768 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4769 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4770 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4771 }
4772 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4773 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4774 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4775 free(m_desc_buffer_ptr[index].buf_addr);
4776 m_desc_buffer_ptr[index].buf_addr = NULL;
4777 m_desc_buffer_ptr[index].desc_data_size = 0;
4778 }
4779#ifdef USE_ION
4780 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4781#endif
4782 }
4783 }
4784
4785 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004786}
4787
4788OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4789{
Arun Menon906de572013-06-18 17:01:40 -07004790 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004791
Arun Menon906de572013-06-18 17:01:40 -07004792 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4793 return OMX_ErrorBadParameter;
4794 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004795
Arun Menon906de572013-06-18 17:01:40 -07004796 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004797 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004798
Arun Menon906de572013-06-18 17:01:40 -07004799 if (index < drv_ctx.op_buf.actualcount
4800 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004801 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004802 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004803
Arun Menon906de572013-06-18 17:01:40 -07004804 struct vdec_setbuffer_cmd setbuffers;
4805 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4806 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4807 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004808
4809 if (!dynamic_buf_mode) {
Balamurugan Alagarsamye773c582014-12-17 15:10:25 +05304810 if (streaming[CAPTURE_PORT] &&
4811 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) {
4812 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
4813 DEBUG_PRINT_ERROR("STREAMOFF Failed");
4814 } else {
4815 DEBUG_PRINT_LOW("STREAMOFF Successful");
4816 }
4817 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004818#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004819 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004820 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004821 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4822 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4823 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4824 }
Arun Menon906de572013-06-18 17:01:40 -07004825 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004826 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4827 } else {
4828#endif
4829 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4830 if (!secure_mode) {
4831 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4832 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4833 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4834 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4835 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4836 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4837 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4838 }
4839 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4840 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004841#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004842 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004843#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004844 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004845#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004846 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004847#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004848 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004849 if (release_output_done()) {
4850 free_extradata();
4851 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004852 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004853
Arun Menon906de572013-06-18 17:01:40 -07004854 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004855
4856}
4857
4858OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004859 OMX_BUFFERHEADERTYPE **bufferHdr,
4860 OMX_U32 port,
4861 OMX_PTR appData,
4862 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004863{
Arun Menon906de572013-06-18 17:01:40 -07004864 OMX_BUFFERHEADERTYPE *input = NULL;
4865 unsigned char *buf_addr = NULL;
4866 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4867 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004868
Arun Menon906de572013-06-18 17:01:40 -07004869 /* Sanity Check*/
4870 if (bufferHdr == NULL) {
4871 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004872 }
4873
Arun Menon906de572013-06-18 17:01:40 -07004874 if (m_inp_heap_ptr == NULL) {
4875 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4876 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4877 drv_ctx.ip_buf.actualcount);
4878 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4879 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4880 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004881
Arun Menon8544ead2014-05-08 17:42:29 -07004882 if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
4883 DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004884 return OMX_ErrorInsufficientResources;
4885 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004886 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004887
Arun Menon906de572013-06-18 17:01:40 -07004888 /*Find a Free index*/
4889 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4890 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004891 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004892 break;
4893 }
4894 }
4895
4896 if (i < drv_ctx.ip_buf.actualcount) {
4897 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4898
4899 if (buf_addr == NULL) {
4900 return OMX_ErrorInsufficientResources;
4901 }
4902
4903 *bufferHdr = (m_inp_heap_ptr + i);
4904 input = *bufferHdr;
4905 BITMASK_SET(&m_heap_inp_bm_count,i);
4906
4907 input->pBuffer = (OMX_U8 *)buf_addr;
4908 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4909 input->nVersion.nVersion = OMX_SPEC_VERSION;
4910 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4911 input->pAppPrivate = appData;
4912 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004913 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004914 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004915 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004916 /*Add the Buffers to freeq*/
4917 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4918 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004919 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004920 return OMX_ErrorInsufficientResources;
4921 }
4922 } else {
4923 return OMX_ErrorBadParameter;
4924 }
4925
4926 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004927
4928}
4929
4930
4931/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004932 FUNCTION
4933 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004934
Arun Menon906de572013-06-18 17:01:40 -07004935 DESCRIPTION
4936 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004937
Arun Menon906de572013-06-18 17:01:40 -07004938 PARAMETERS
4939 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004940
Arun Menon906de572013-06-18 17:01:40 -07004941 RETURN VALUE
4942 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004943
Arun Menon906de572013-06-18 17:01:40 -07004944 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004945OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004946 OMX_IN OMX_HANDLETYPE hComp,
4947 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4948 OMX_IN OMX_U32 port,
4949 OMX_IN OMX_PTR appData,
4950 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004951{
4952
Arun Menon906de572013-06-18 17:01:40 -07004953 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4954 struct vdec_setbuffer_cmd setbuffers;
4955 OMX_BUFFERHEADERTYPE *input = NULL;
4956 unsigned i = 0;
4957 unsigned char *buf_addr = NULL;
4958 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004959
Arun Menon906de572013-06-18 17:01:40 -07004960 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004961 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004962 bytes, drv_ctx.ip_buf.buffer_size);
4963 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004964 }
4965
Arun Menon906de572013-06-18 17:01:40 -07004966 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004967 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004968 drv_ctx.ip_buf.actualcount,
4969 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004970
Arun Menon906de572013-06-18 17:01:40 -07004971 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4972 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4973
4974 if (m_inp_mem_ptr == NULL) {
4975 return OMX_ErrorInsufficientResources;
4976 }
4977
4978 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4979 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4980
4981 if (drv_ctx.ptr_inputbuffer == NULL) {
4982 return OMX_ErrorInsufficientResources;
4983 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004984#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004985 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4986 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004987
Arun Menon906de572013-06-18 17:01:40 -07004988 if (drv_ctx.ip_buf_ion_info == NULL) {
4989 return OMX_ErrorInsufficientResources;
4990 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004991#endif
4992
Arun Menon906de572013-06-18 17:01:40 -07004993 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4994 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004995#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004996 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004997#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004998 }
4999 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005000
Arun Menon906de572013-06-18 17:01:40 -07005001 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
5002 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005003 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005004 break;
5005 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005006 }
Arun Menon906de572013-06-18 17:01:40 -07005007
5008 if (i < drv_ctx.ip_buf.actualcount) {
5009 struct v4l2_buffer buf;
5010 struct v4l2_plane plane;
5011 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005012 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07005013#ifdef USE_ION
5014 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
5015 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
5016 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
5017 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
5018 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
5019 return OMX_ErrorInsufficientResources;
5020 }
5021 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
5022#else
5023 pmem_fd = open (MEM_DEVICE,O_RDWR);
5024
5025 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005026 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005027 return OMX_ErrorInsufficientResources;
5028 }
5029
5030 if (pmem_fd == 0) {
5031 pmem_fd = open (MEM_DEVICE,O_RDWR);
5032
5033 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005034 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005035 return OMX_ErrorInsufficientResources;
5036 }
5037 }
5038
5039 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
5040 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005041 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005042 close(pmem_fd);
5043 return OMX_ErrorInsufficientResources;
5044 }
5045#endif
5046 if (!secure_mode) {
5047 buf_addr = (unsigned char *)mmap(NULL,
5048 drv_ctx.ip_buf.buffer_size,
5049 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
5050
5051 if (buf_addr == MAP_FAILED) {
5052 close(pmem_fd);
5053#ifdef USE_ION
5054 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
5055#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005056 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005057 return OMX_ErrorInsufficientResources;
5058 }
5059 }
5060 *bufferHdr = (m_inp_mem_ptr + i);
5061 if (secure_mode)
5062 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
5063 else
5064 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
5065 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
5066 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
5067 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
5068 drv_ctx.ptr_inputbuffer [i].offset = 0;
5069
5070
5071 buf.index = i;
5072 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5073 buf.memory = V4L2_MEMORY_USERPTR;
5074 plane.bytesused = 0;
5075 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
5076 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
5077 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
5078 plane.reserved[1] = 0;
5079 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
5080 buf.m.planes = &plane;
5081 buf.length = 1;
5082
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005083 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07005084 drv_ctx.ptr_inputbuffer[i].bufferaddr);
5085
5086 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5087
5088 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005089 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07005090 /*TODO: How to handle this case */
5091 return OMX_ErrorInsufficientResources;
5092 }
5093
5094 input = *bufferHdr;
5095 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005096 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07005097 if (secure_mode)
5098 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
5099 else
5100 input->pBuffer = (OMX_U8 *)buf_addr;
5101 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5102 input->nVersion.nVersion = OMX_SPEC_VERSION;
5103 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
5104 input->pAppPrivate = appData;
5105 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
5106 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
5107
5108 if (drv_ctx.disable_dmx) {
5109 eRet = allocate_desc_buffer(i);
5110 }
5111 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005112 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07005113 eRet = OMX_ErrorInsufficientResources;
5114 }
5115 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005116}
5117
5118
5119/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005120 FUNCTION
5121 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005122
Arun Menon906de572013-06-18 17:01:40 -07005123 DESCRIPTION
5124 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07005125
Arun Menon906de572013-06-18 17:01:40 -07005126 PARAMETERS
5127 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005128
Arun Menon906de572013-06-18 17:01:40 -07005129 RETURN VALUE
5130 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005131
Arun Menon906de572013-06-18 17:01:40 -07005132 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005133OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07005134 OMX_IN OMX_HANDLETYPE hComp,
5135 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5136 OMX_IN OMX_U32 port,
5137 OMX_IN OMX_PTR appData,
5138 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005139{
Arun Menon906de572013-06-18 17:01:40 -07005140 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5141 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
5142 unsigned i= 0; // Temporary counter
5143 struct vdec_setbuffer_cmd setbuffers;
5144 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005145#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005146 int ion_device_fd =-1;
5147 struct ion_allocation_data ion_alloc_data;
5148 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005149#endif
Arun Menon906de572013-06-18 17:01:40 -07005150 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005151 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07005152 drv_ctx.op_buf.actualcount,
5153 drv_ctx.op_buf.buffer_size);
5154 int nBufHdrSize = 0;
5155 int nPlatformEntrySize = 0;
5156 int nPlatformListSize = 0;
5157 int nPMEMInfoSize = 0;
5158 int pmem_fd = -1;
5159 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005160
Arun Menon906de572013-06-18 17:01:40 -07005161 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
5162 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
5163 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005164
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005165 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07005166 drv_ctx.op_buf.actualcount);
5167 nBufHdrSize = drv_ctx.op_buf.actualcount *
5168 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005169
Arun Menon906de572013-06-18 17:01:40 -07005170 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
5171 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
5172 nPlatformListSize = drv_ctx.op_buf.actualcount *
5173 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
5174 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
5175 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005176
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005177 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07005178 sizeof(OMX_BUFFERHEADERTYPE),
5179 nPMEMInfoSize,
5180 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005181 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07005182 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005183#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005184 ion_device_fd = alloc_map_ion_memory(
5185 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
5186 drv_ctx.op_buf.alignment,
5187 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
5188 if (ion_device_fd < 0) {
5189 return OMX_ErrorInsufficientResources;
5190 }
5191 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005192#else
Arun Menon906de572013-06-18 17:01:40 -07005193 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005194
Arun Menon906de572013-06-18 17:01:40 -07005195 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005196 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005197 drv_ctx.op_buf.buffer_size);
5198 return OMX_ErrorInsufficientResources;
5199 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005200
Arun Menon906de572013-06-18 17:01:40 -07005201 if (pmem_fd == 0) {
5202 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005203
Arun Menon906de572013-06-18 17:01:40 -07005204 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005205 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005206 drv_ctx.op_buf.buffer_size);
5207 return OMX_ErrorInsufficientResources;
5208 }
5209 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005210
Arun Menon906de572013-06-18 17:01:40 -07005211 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5212 drv_ctx.op_buf.actualcount,
5213 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005214 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005215 close(pmem_fd);
5216 return OMX_ErrorInsufficientResources;
5217 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005218#endif
Arun Menon906de572013-06-18 17:01:40 -07005219 if (!secure_mode) {
5220 pmem_baseaddress = (unsigned char *)mmap(NULL,
5221 (drv_ctx.op_buf.buffer_size *
5222 drv_ctx.op_buf.actualcount),
5223 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5224 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005225 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07005226 drv_ctx.op_buf.buffer_size);
5227 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005228#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005229 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005230#endif
Arun Menon906de572013-06-18 17:01:40 -07005231 return OMX_ErrorInsufficientResources;
5232 }
5233 }
5234 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5235 // Alloc mem for platform specific info
5236 char *pPtr=NULL;
5237 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5238 nPMEMInfoSize,1);
5239 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5240 calloc (sizeof(struct vdec_bufferpayload),
5241 drv_ctx.op_buf.actualcount);
5242 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5243 calloc (sizeof (struct vdec_output_frameinfo),
5244 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005245 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
5246 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
5247 return OMX_ErrorInsufficientResources;
5248 }
5249
Arun Menon906de572013-06-18 17:01:40 -07005250#ifdef USE_ION
5251 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5252 calloc (sizeof(struct vdec_ion),
5253 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005254 if (!drv_ctx.op_buf_ion_info) {
5255 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
5256 return OMX_ErrorInsufficientResources;
5257 }
Arun Menon906de572013-06-18 17:01:40 -07005258#endif
5259
5260 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5261 && drv_ctx.ptr_respbuffer) {
5262 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5263 (drv_ctx.op_buf.buffer_size *
5264 drv_ctx.op_buf.actualcount);
5265 bufHdr = m_out_mem_ptr;
5266 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5267 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5268 (((char *) m_platform_list) + nPlatformListSize);
5269 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5270 (((char *) m_platform_entry) + nPlatformEntrySize);
5271 pPlatformList = m_platform_list;
5272 pPlatformEntry = m_platform_entry;
5273 pPMEMInfo = m_pmem_info;
5274
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005275 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07005276
5277 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005278 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
5279 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07005280 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
5281 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5282 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5283 // Set the values when we determine the right HxW param
5284 bufHdr->nAllocLen = bytes;
5285 bufHdr->nFilledLen = 0;
5286 bufHdr->pAppPrivate = appData;
5287 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5288 // Platform specific PMEM Information
5289 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005290 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005291 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5292 pPlatformEntry->entry = pPMEMInfo;
5293 // Initialize the Platform List
5294 pPlatformList->nEntries = 1;
5295 pPlatformList->entryList = pPlatformEntry;
5296 // Keep pBuffer NULL till vdec is opened
5297 bufHdr->pBuffer = NULL;
5298 bufHdr->nOffset = 0;
5299
5300 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5301 pPMEMInfo->pmem_fd = 0;
5302 bufHdr->pPlatformPrivate = pPlatformList;
5303
5304 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5305 m_pmem_info[i].pmem_fd = pmem_fd;
5306#ifdef USE_ION
5307 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5308 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5309 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5310#endif
5311
5312 /*Create a mapping between buffers*/
5313 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5314 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5315 &drv_ctx.ptr_outputbuffer[i];
5316 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5317 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5318 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305319 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5320 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5321 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005322
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005323 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005324 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5325 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5326 // Move the buffer and buffer header pointers
5327 bufHdr++;
5328 pPMEMInfo++;
5329 pPlatformEntry++;
5330 pPlatformList++;
5331 }
5332 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005333 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005334 m_out_mem_ptr, pPtr);
5335 if (m_out_mem_ptr) {
5336 free(m_out_mem_ptr);
5337 m_out_mem_ptr = NULL;
5338 }
5339 if (pPtr) {
5340 free(pPtr);
5341 pPtr = NULL;
5342 }
5343 if (drv_ctx.ptr_outputbuffer) {
5344 free(drv_ctx.ptr_outputbuffer);
5345 drv_ctx.ptr_outputbuffer = NULL;
5346 }
5347 if (drv_ctx.ptr_respbuffer) {
5348 free(drv_ctx.ptr_respbuffer);
5349 drv_ctx.ptr_respbuffer = NULL;
5350 }
5351#ifdef USE_ION
5352 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005353 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005354 free(drv_ctx.op_buf_ion_info);
5355 drv_ctx.op_buf_ion_info = NULL;
5356 }
5357#endif
5358 eRet = OMX_ErrorInsufficientResources;
5359 }
5360 if (eRet == OMX_ErrorNone)
5361 eRet = allocate_extradata();
5362 }
5363
5364 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5365 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005366 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005367 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005368 }
5369 }
Arun Menon906de572013-06-18 17:01:40 -07005370
5371 if (eRet == OMX_ErrorNone) {
5372 if (i < drv_ctx.op_buf.actualcount) {
5373 struct v4l2_buffer buf;
5374 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5375 int rc;
5376 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5377
5378 drv_ctx.ptr_outputbuffer[i].buffer_len =
5379 drv_ctx.op_buf.buffer_size;
5380
5381 *bufferHdr = (m_out_mem_ptr + i );
5382 if (secure_mode) {
5383 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5384 }
5385 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5386
5387 buf.index = i;
5388 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5389 buf.memory = V4L2_MEMORY_USERPTR;
5390 plane[0].length = drv_ctx.op_buf.buffer_size;
5391 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5392 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005393#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005394 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005395#endif
Arun Menon906de572013-06-18 17:01:40 -07005396 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5397 plane[0].data_offset = 0;
5398 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5399 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5400 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5401 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 -07005402#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005403 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005404#endif
Arun Menon906de572013-06-18 17:01:40 -07005405 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5406 plane[extra_idx].data_offset = 0;
5407 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005408 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005409 return OMX_ErrorBadParameter;
5410 }
5411 buf.m.planes = plane;
5412 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005413 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 -07005414 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5415 if (rc) {
5416 /*TODO: How to handle this case */
5417 return OMX_ErrorInsufficientResources;
5418 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005419
Arun Menon906de572013-06-18 17:01:40 -07005420 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5421 enum v4l2_buf_type buf_type;
5422 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5423 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5424 if (rc) {
5425 return OMX_ErrorInsufficientResources;
5426 } else {
5427 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005428 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005429 }
5430 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005431
Arun Menon906de572013-06-18 17:01:40 -07005432 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5433 (*bufferHdr)->pAppPrivate = appData;
5434 BITMASK_SET(&m_out_bm_count,i);
5435 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005436 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005437 eRet = OMX_ErrorInsufficientResources;
5438 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005439 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005440
Arun Menon906de572013-06-18 17:01:40 -07005441 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005442}
5443
5444
5445// AllocateBuffer -- API Call
5446/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005447 FUNCTION
5448 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005449
Arun Menon906de572013-06-18 17:01:40 -07005450 DESCRIPTION
5451 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005452
Arun Menon906de572013-06-18 17:01:40 -07005453 PARAMETERS
5454 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005455
Arun Menon906de572013-06-18 17:01:40 -07005456 RETURN VALUE
5457 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005458
Arun Menon906de572013-06-18 17:01:40 -07005459 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005460OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005461 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5462 OMX_IN OMX_U32 port,
5463 OMX_IN OMX_PTR appData,
5464 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005465{
5466 unsigned i = 0;
5467 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5468
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005469 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005470 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005471 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005472 return OMX_ErrorInvalidState;
5473 }
5474
Arun Menon906de572013-06-18 17:01:40 -07005475 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5476 if (arbitrary_bytes) {
5477 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5478 } else {
5479 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5480 }
5481 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005482 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5483 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005484 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005485 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005486 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005487 }
5488 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005489 if (eRet == OMX_ErrorNone) {
5490 if (allocate_done()) {
5491 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005492 // Send the callback now
5493 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5494 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005495 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005496 }
5497 }
Arun Menon906de572013-06-18 17:01:40 -07005498 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5499 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5500 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5501 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005502 OMX_CORE_INPUT_PORT_INDEX,
5503 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005504 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005505 }
Arun Menon906de572013-06-18 17:01:40 -07005506 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5507 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5508 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005509 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005510 OMX_CORE_OUTPUT_PORT_INDEX,
5511 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005512 }
5513 }
5514 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005515 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005516 return eRet;
5517}
5518
5519// Free Buffer - API call
5520/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005521 FUNCTION
5522 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005523
Arun Menon906de572013-06-18 17:01:40 -07005524 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005525
Arun Menon906de572013-06-18 17:01:40 -07005526 PARAMETERS
5527 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005528
Arun Menon906de572013-06-18 17:01:40 -07005529 RETURN VALUE
5530 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005531
Arun Menon906de572013-06-18 17:01:40 -07005532 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005533OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005534 OMX_IN OMX_U32 port,
5535 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005536{
5537 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5538 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005539 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005540
Arun Menon906de572013-06-18 17:01:40 -07005541 if (m_state == OMX_StateIdle &&
5542 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005543 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005544 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5545 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005546 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005547 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5548 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5549 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5550 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005551 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005552 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005553 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005554 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005555 OMX_ErrorPortUnpopulated,
5556 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005557
5558 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005559 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005560 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005561 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005562 OMX_ErrorPortUnpopulated,
5563 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005564 }
5565
Arun Menon906de572013-06-18 17:01:40 -07005566 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5567 /*Check if arbitrary bytes*/
5568 if (!arbitrary_bytes && !input_use_buffer)
5569 nPortIndex = buffer - m_inp_mem_ptr;
5570 else
5571 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005572
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005573 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005574 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5575 // Clear the bit associated with it.
5576 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5577 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5578 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005579
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005580 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005581 if (m_phdr_pmem_ptr)
5582 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5583 } else {
5584 if (arbitrary_bytes) {
5585 if (m_phdr_pmem_ptr)
5586 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5587 else
5588 free_input_buffer(nPortIndex,NULL);
5589 } else
5590 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005591 }
Arun Menon906de572013-06-18 17:01:40 -07005592 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305593 if(release_input_done())
5594 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005595 /*Free the Buffer Header*/
5596 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005597 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005598 free_input_buffer_header();
5599 }
5600 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005601 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005602 eRet = OMX_ErrorBadPortIndex;
5603 }
5604
Arun Menon906de572013-06-18 17:01:40 -07005605 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5606 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005607 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005608 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5609 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005610 OMX_CORE_INPUT_PORT_INDEX,
5611 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005612 }
Arun Menon906de572013-06-18 17:01:40 -07005613 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005614 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005615 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005616 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005617 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005618 // Clear the bit associated with it.
5619 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5620 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005621 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005622
Surajit Podder12aefac2013-08-06 18:43:32 +05305623 if(release_output_done()) {
5624 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5625 }
Arun Menon906de572013-06-18 17:01:40 -07005626 if (release_output_done()) {
5627 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005628 }
Arun Menon906de572013-06-18 17:01:40 -07005629 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005630 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005631 eRet = OMX_ErrorBadPortIndex;
5632 }
Arun Menon906de572013-06-18 17:01:40 -07005633 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5634 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005635 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005636
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005637 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005638 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005639#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005640 if (m_enable_android_native_buffers) {
5641 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5642 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5643 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005644#endif
5645
Arun Menon906de572013-06-18 17:01:40 -07005646 post_event(OMX_CommandPortDisable,
5647 OMX_CORE_OUTPUT_PORT_INDEX,
5648 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005649 }
Arun Menon906de572013-06-18 17:01:40 -07005650 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005651 eRet = OMX_ErrorBadPortIndex;
5652 }
Arun Menon906de572013-06-18 17:01:40 -07005653 if ((eRet == OMX_ErrorNone) &&
5654 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5655 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005656 // Send the callback now
5657 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5658 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005659 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005660 }
5661 }
5662 return eRet;
5663}
5664
5665
5666/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005667 FUNCTION
5668 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005669
Arun Menon906de572013-06-18 17:01:40 -07005670 DESCRIPTION
5671 This routine is used to push the encoded video frames to
5672 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005673
Arun Menon906de572013-06-18 17:01:40 -07005674 PARAMETERS
5675 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005676
Arun Menon906de572013-06-18 17:01:40 -07005677 RETURN VALUE
5678 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005679
Arun Menon906de572013-06-18 17:01:40 -07005680 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005681OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005682 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005683{
Arun Menon906de572013-06-18 17:01:40 -07005684 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5685 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005686
Arun Menon906de572013-06-18 17:01:40 -07005687 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005688 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005689 return OMX_ErrorInvalidState;
5690 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005691
Arun Menon906de572013-06-18 17:01:40 -07005692 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005693 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005694 return OMX_ErrorBadParameter;
5695 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005696
Arun Menon906de572013-06-18 17:01:40 -07005697 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005698 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005699 return OMX_ErrorIncorrectStateOperation;
5700 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005701
Arun Menon906de572013-06-18 17:01:40 -07005702 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005703 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005704 return OMX_ErrorBadPortIndex;
5705 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005706
5707#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005708 if (iDivXDrmDecrypt) {
5709 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5710 if (drmErr != OMX_ErrorNone) {
5711 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005712 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005713 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005714 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005715#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005716 if (perf_flag) {
5717 if (!latency) {
5718 dec_time.stop();
5719 latency = dec_time.processing_time_us();
5720 dec_time.start();
5721 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005722 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005723
Arun Menon906de572013-06-18 17:01:40 -07005724 if (arbitrary_bytes) {
5725 nBufferIndex = buffer - m_inp_heap_ptr;
5726 } else {
5727 if (input_use_buffer == true) {
5728 nBufferIndex = buffer - m_inp_heap_ptr;
5729 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5730 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5731 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5732 buffer = &m_inp_mem_ptr[nBufferIndex];
5733 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5734 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5735 } else {
5736 nBufferIndex = buffer - m_inp_mem_ptr;
5737 }
5738 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005739
Arun Menon906de572013-06-18 17:01:40 -07005740 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005741 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005742 return OMX_ErrorBadParameter;
5743 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005744
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005745 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5746 codec_config_flag = true;
5747 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5748 }
5749
Arun Menon906de572013-06-18 17:01:40 -07005750 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5751 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5752 if (arbitrary_bytes) {
5753 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005754 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005755 } else {
Arun Menon906de572013-06-18 17:01:40 -07005756 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5757 }
Praveen Chavanece713f2014-12-10 18:00:04 -08005758 time_stamp_dts.insert_timestamp(buffer);
Arun Menon906de572013-06-18 17:01:40 -07005759 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005760}
5761
5762/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005763 FUNCTION
5764 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005765
Arun Menon906de572013-06-18 17:01:40 -07005766 DESCRIPTION
5767 This routine is used to push the encoded video frames to
5768 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005769
Arun Menon906de572013-06-18 17:01:40 -07005770 PARAMETERS
5771 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005772
Arun Menon906de572013-06-18 17:01:40 -07005773 RETURN VALUE
5774 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005775
Arun Menon906de572013-06-18 17:01:40 -07005776 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005777OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005778 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005779{
Arun Menon906de572013-06-18 17:01:40 -07005780 int push_cnt = 0,i=0;
5781 unsigned nPortIndex = 0;
5782 OMX_ERRORTYPE ret = OMX_ErrorNone;
5783 struct vdec_input_frameinfo frameinfo;
5784 struct vdec_bufferpayload *temp_buffer;
5785 struct vdec_seqheader seq_header;
5786 bool port_setting_changed = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005787
Arun Menon906de572013-06-18 17:01:40 -07005788 /*Should we generate a Aync error event*/
5789 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005790 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005791 return OMX_ErrorBadParameter;
5792 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005793
Arun Menon906de572013-06-18 17:01:40 -07005794 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005795
Arun Menon906de572013-06-18 17:01:40 -07005796 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005797 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005798 nPortIndex);
5799 return OMX_ErrorBadParameter;
5800 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005801
Arun Menon906de572013-06-18 17:01:40 -07005802 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005803
Arun Menon906de572013-06-18 17:01:40 -07005804 /* return zero length and not an EOS buffer */
5805 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5806 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005807 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005808 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5809 OMX_COMPONENT_GENERATE_EBD);
5810 return OMX_ErrorNone;
5811 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005812
c_sridur0af9cef2015-02-05 12:07:17 +05305813 if (input_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005814 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005815 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5816 OMX_COMPONENT_GENERATE_EBD);
5817 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005818 }
5819
Arun Menon906de572013-06-18 17:01:40 -07005820 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005821
Surajit Podderd2644d52013-08-28 17:59:06 +05305822 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005823 return OMX_ErrorBadParameter;
5824 }
5825 /* If its first frame, H264 codec and reject is true, then parse the nal
5826 and get the profile. Based on this, reject the clip playback */
5827 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5828 m_reject_avc_1080p_mp) {
5829 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005830 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005831 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5832 NALU_TYPE_SPS);
5833 m_profile = h264_parser->get_profile();
5834 ret = is_video_session_supported();
5835 if (ret) {
5836 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5837 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5838 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5839 m_state = OMX_StateInvalid;
5840 return OMX_ErrorNone;
5841 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005842 }
5843
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005844 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005845 /*for use buffer we need to memcpy the data*/
5846 temp_buffer->buffer_len = buffer->nFilledLen;
5847
5848 if (input_use_buffer) {
5849 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5850 if (arbitrary_bytes) {
5851 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5852 } else {
5853 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5854 buffer->nFilledLen);
5855 }
5856 } else {
5857 return OMX_ErrorBadParameter;
5858 }
5859
5860 }
5861
5862 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5863 frameinfo.client_data = (void *) buffer;
5864 frameinfo.datalen = temp_buffer->buffer_len;
5865 frameinfo.flags = 0;
5866 frameinfo.offset = buffer->nOffset;
5867 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5868 frameinfo.pmem_offset = temp_buffer->offset;
5869 frameinfo.timestamp = buffer->nTimeStamp;
5870 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5871 DEBUG_PRINT_LOW("ETB: dmx enabled");
5872 if (m_demux_entries == 0) {
5873 extract_demux_addr_offsets(buffer);
5874 }
5875
5876 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5877 handle_demux_data(buffer);
5878 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5879 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5880 } else {
5881 frameinfo.desc_addr = NULL;
5882 frameinfo.desc_size = 0;
5883 }
5884 if (!arbitrary_bytes) {
5885 frameinfo.flags |= buffer->nFlags;
5886 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005887
5888#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005889 if (m_debug_timestamp) {
5890 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005891 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005892 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5893 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005894 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005895 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5896 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005897 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005898#endif
5899
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005900log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005901
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005902if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005903 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5904 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5905 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005906
Arun Menon906de572013-06-18 17:01:40 -07005907 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005908 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005909 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5910 h264_scratch.nFilledLen = 0;
5911 nal_count = 0;
5912 look_ahead_nal = false;
5913 frame_count = 0;
5914 if (m_frame_parser.mutils)
5915 m_frame_parser.mutils->initialize_frame_checking_environment();
5916 m_frame_parser.flush();
5917 h264_last_au_ts = LLONG_MAX;
5918 h264_last_au_flags = 0;
5919 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5920 m_demux_entries = 0;
5921 }
5922 struct v4l2_buffer buf;
5923 struct v4l2_plane plane;
5924 memset( (void *)&buf, 0, sizeof(buf));
5925 memset( (void *)&plane, 0, sizeof(plane));
5926 int rc;
5927 unsigned long print_count;
5928 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005929 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005930 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005931 }
5932 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5933 buf.index = nPortIndex;
5934 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5935 buf.memory = V4L2_MEMORY_USERPTR;
5936 plane.bytesused = temp_buffer->buffer_len;
5937 plane.length = drv_ctx.ip_buf.buffer_size;
5938 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5939 (unsigned long)temp_buffer->offset;
5940 plane.reserved[0] = temp_buffer->pmem_fd;
5941 plane.reserved[1] = temp_buffer->offset;
5942 plane.data_offset = 0;
5943 buf.m.planes = &plane;
5944 buf.length = 1;
5945 if (frameinfo.timestamp >= LLONG_MAX) {
5946 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5947 }
5948 //assumption is that timestamp is in milliseconds
5949 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5950 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5951 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5952 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005953
Pushkaraj Patil20bd6bf2014-12-22 19:33:08 +05305954 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5955 DEBUG_PRINT_LOW("Increment codec_config buffer counter");
5956 android_atomic_inc(&m_queued_codec_config_count);
5957 }
5958
Arun Menon906de572013-06-18 17:01:40 -07005959 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5960 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005961 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005962 return OMX_ErrorHardware;
5963 }
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -07005964
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005965 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5966 codec_config_flag = false;
5967 }
Arun Menon906de572013-06-18 17:01:40 -07005968 if (!streaming[OUTPUT_PORT]) {
5969 enum v4l2_buf_type buf_type;
5970 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005971
Arun Menon906de572013-06-18 17:01:40 -07005972 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005973 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005974 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5975 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005976 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005977 streaming[OUTPUT_PORT] = true;
Jia Meng1e236c82014-04-03 10:54:39 +08005978 } else if (errno == EBUSY) {
5979 DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
5980 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
5981 OMX_COMPONENT_GENERATE_EBD);
5982 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005983 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005984 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005985 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
Jia Meng1e236c82014-04-03 10:54:39 +08005986 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
Arun Menon906de572013-06-18 17:01:40 -07005987 OMX_COMPONENT_GENERATE_EBD);
5988 return OMX_ErrorBadParameter;
5989 }
5990 }
5991 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5992 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005993
Arun Menon906de572013-06-18 17:01:40 -07005994 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005995}
5996
5997/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005998 FUNCTION
5999 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07006000
Arun Menon906de572013-06-18 17:01:40 -07006001 DESCRIPTION
6002 IL client uses this method to release the frame buffer
6003 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006004
Arun Menon906de572013-06-18 17:01:40 -07006005 PARAMETERS
6006 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006007
Arun Menon906de572013-06-18 17:01:40 -07006008 RETURN VALUE
6009 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006010
Arun Menon906de572013-06-18 17:01:40 -07006011 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006012OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006013 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006014{
Jia Meng2d51b932014-07-10 14:02:54 +08006015 unsigned nPortIndex = 0;
Arun Menonbdb80b02013-08-12 17:45:54 -07006016 if (dynamic_buf_mode) {
6017 private_handle_t *handle = NULL;
6018 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07006019 unsigned int nPortIndex = 0;
6020
6021 if (!buffer || !buffer->pBuffer) {
Arun Menon8544ead2014-05-08 17:42:29 -07006022 DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
Arun Menonbdb80b02013-08-12 17:45:54 -07006023 return OMX_ErrorBadParameter;
6024 }
6025
6026 //get the buffer type and fd info
6027 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
6028 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08006029 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
6030
6031 if (!handle) {
6032 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
6033 return OMX_ErrorBadParameter;
6034 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006035 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
6036 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6037 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08006038 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006039
6040 //Store private handle from GraphicBuffer
6041 native_buffer[nPortIndex].privatehandle = handle;
6042 native_buffer[nPortIndex].nativehandle = handle;
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006043
6044 //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
6045 //this with a more sane size so that we don't compensate in rest of code
6046 //We'll restore this size later on, so that it's transparent to client
6047 buffer->nFilledLen = 0;
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07006048 buffer->nAllocLen = handle->size;
Arun Menonbdb80b02013-08-12 17:45:54 -07006049 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006050
Arun Menon906de572013-06-18 17:01:40 -07006051 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006052 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07006053 return OMX_ErrorInvalidState;
6054 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006055
Arun Menon906de572013-06-18 17:01:40 -07006056 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006057 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07006058 return OMX_ErrorIncorrectStateOperation;
6059 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006060
Jia Meng2d51b932014-07-10 14:02:54 +08006061 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07006062 if (buffer == NULL ||
Jia Meng2d51b932014-07-10 14:02:54 +08006063 (nPortIndex >= drv_ctx.op_buf.actualcount)) {
6064 DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
6065 nPortIndex, drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07006066 return OMX_ErrorBadParameter;
6067 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006068
Arun Menon906de572013-06-18 17:01:40 -07006069 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006070 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07006071 return OMX_ErrorBadPortIndex;
6072 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006073
Arun Menon906de572013-06-18 17:01:40 -07006074 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6075 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
6076 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006077}
6078/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006079 FUNCTION
6080 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07006081
Arun Menon906de572013-06-18 17:01:40 -07006082 DESCRIPTION
6083 IL client uses this method to release the frame buffer
6084 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006085
Arun Menon906de572013-06-18 17:01:40 -07006086 PARAMETERS
6087 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006088
Arun Menon906de572013-06-18 17:01:40 -07006089 RETURN VALUE
6090 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006091
Arun Menon906de572013-06-18 17:01:40 -07006092 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006093OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07006094 OMX_IN OMX_HANDLETYPE hComp,
6095 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006096{
Arun Menon906de572013-06-18 17:01:40 -07006097 OMX_ERRORTYPE nRet = OMX_ErrorNone;
6098 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
6099 unsigned nPortIndex = 0;
6100 struct vdec_fillbuffer_cmd fillbuffer;
6101 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
6102 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006103
Arun Menon906de572013-06-18 17:01:40 -07006104 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07006105
Jia Meng2d51b932014-07-10 14:02:54 +08006106 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) {
6107 DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
6108 nPortIndex, drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07006109 return OMX_ErrorBadParameter;
Jia Meng2d51b932014-07-10 14:02:54 +08006110 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006111
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006112 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006113 bufferAdd, bufferAdd->pBuffer);
6114 /*Return back the output buffer to client*/
6115 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006116 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07006117 buffer->nFilledLen = 0;
6118 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6119 return OMX_ErrorNone;
6120 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08006121
6122 if (dynamic_buf_mode) {
6123 //map the buffer handle based on the size set on output port definition.
6124 if (!secure_mode) {
6125 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
6126 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
6127 PROT_READ|PROT_WRITE, MAP_SHARED,
6128 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
6129 }
6130 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
6131 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
6132 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
6133 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
6134 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
6135 }
6136
Arun Menon906de572013-06-18 17:01:40 -07006137 pending_output_buffers++;
6138 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
6139 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
6140 if (ptr_respbuffer) {
6141 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
6142 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006143
Arun Menon906de572013-06-18 17:01:40 -07006144 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
6145 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
6146 buffer->nFilledLen = 0;
6147 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6148 pending_output_buffers--;
6149 return OMX_ErrorBadParameter;
6150 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006151
Arun Menon906de572013-06-18 17:01:40 -07006152 int rc = 0;
6153 struct v4l2_buffer buf;
6154 struct v4l2_plane plane[VIDEO_MAX_PLANES];
6155 memset( (void *)&buf, 0, sizeof(buf));
6156 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Arun Menon8544ead2014-05-08 17:42:29 -07006157 unsigned int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006158
Arun Menon906de572013-06-18 17:01:40 -07006159 buf.index = nPortIndex;
6160 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6161 buf.memory = V4L2_MEMORY_USERPTR;
6162 plane[0].bytesused = buffer->nFilledLen;
6163 plane[0].length = drv_ctx.op_buf.buffer_size;
6164 plane[0].m.userptr =
6165 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
6166 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6167 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
6168 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6169 plane[0].data_offset = 0;
6170 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
6171 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
6172 plane[extra_idx].bytesused = 0;
6173 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
6174 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 -07006175#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07006176 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006177#endif
Arun Menon906de572013-06-18 17:01:40 -07006178 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
6179 plane[extra_idx].data_offset = 0;
6180 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Arun Menon8544ead2014-05-08 17:42:29 -07006181 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07006182 return OMX_ErrorBadParameter;
6183 }
6184 buf.m.planes = plane;
6185 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006186 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07006187 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
6188
Arun Menon906de572013-06-18 17:01:40 -07006189 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6190 if (rc) {
6191 /*TODO: How to handle this case */
6192 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6193 }
Arun Menon906de572013-06-18 17:01:40 -07006194return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006195}
6196
6197/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006198 FUNCTION
6199 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07006200
Arun Menon906de572013-06-18 17:01:40 -07006201 DESCRIPTION
6202 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006203
Arun Menon906de572013-06-18 17:01:40 -07006204 PARAMETERS
6205 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006206
Arun Menon906de572013-06-18 17:01:40 -07006207 RETURN VALUE
6208 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006209
Arun Menon906de572013-06-18 17:01:40 -07006210 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006211OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006212 OMX_IN OMX_CALLBACKTYPE* callbacks,
6213 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006214{
6215
Arun Menon906de572013-06-18 17:01:40 -07006216 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006217 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07006218 m_cb.EventHandler,m_cb.FillBufferDone);
6219 m_app_data = appData;
6220 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006221}
6222
6223/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006224 FUNCTION
6225 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07006226
Arun Menon906de572013-06-18 17:01:40 -07006227 DESCRIPTION
6228 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006229
Arun Menon906de572013-06-18 17:01:40 -07006230 PARAMETERS
6231 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006232
Arun Menon906de572013-06-18 17:01:40 -07006233 RETURN VALUE
6234 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006235
Arun Menon906de572013-06-18 17:01:40 -07006236 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006237OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6238{
6239#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006240 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006241 delete iDivXDrmDecrypt;
6242 iDivXDrmDecrypt=NULL;
6243 }
6244#endif //_ANDROID_
6245
Shalaj Jain286b0062013-02-21 20:35:48 -08006246 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07006247 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006248 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07006249 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006250 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07006251 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006252 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006253 }
6254
6255 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006256 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006257 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07006258 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
6259 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006260 }
6261#ifdef _ANDROID_ICS_
6262 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6263#endif
6264 }
6265
6266 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006267 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006268 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07006269 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
6270 if (m_inp_mem_ptr)
6271 free_input_buffer (i,&m_inp_mem_ptr[i]);
6272 else
6273 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006274 }
6275 }
6276 free_input_buffer_header();
6277 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07006278 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006279 free(h264_scratch.pBuffer);
6280 h264_scratch.pBuffer = NULL;
6281 }
6282
Arun Menon906de572013-06-18 17:01:40 -07006283 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006284 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07006285 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006286 }
6287
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006288 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006289 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006290 delete (m_frame_parser.mutils);
6291 m_frame_parser.mutils = NULL;
6292 }
6293
Arun Menon906de572013-06-18 17:01:40 -07006294 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006295 free(m_platform_list);
6296 m_platform_list = NULL;
6297 }
Arun Menon906de572013-06-18 17:01:40 -07006298 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006299 free(m_vendor_config.pData);
6300 m_vendor_config.pData = NULL;
6301 }
6302
6303 // Reset counters in mesg queues
6304 m_ftb_q.m_size=0;
6305 m_cmd_q.m_size=0;
6306 m_etb_q.m_size=0;
6307 m_ftb_q.m_read = m_ftb_q.m_write =0;
6308 m_cmd_q.m_read = m_cmd_q.m_write =0;
6309 m_etb_q.m_read = m_etb_q.m_write =0;
6310#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006311 if (m_debug_timestamp) {
6312 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006313 }
6314#endif
6315
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006316 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006317 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006318 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006319 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006320
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006321 if (m_debug.infile) {
6322 fclose(m_debug.infile);
6323 m_debug.infile = NULL;
6324 }
6325 if (m_debug.outfile) {
6326 fclose(m_debug.outfile);
6327 m_debug.outfile = NULL;
6328 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006329#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006330 if (outputExtradataFile)
6331 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006332#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006333 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006334 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006335}
6336
6337/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006338 FUNCTION
6339 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006340
Arun Menon906de572013-06-18 17:01:40 -07006341 DESCRIPTION
6342 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006343
Arun Menon906de572013-06-18 17:01:40 -07006344 PARAMETERS
6345 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006346
Arun Menon906de572013-06-18 17:01:40 -07006347 RETURN VALUE
6348 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006349
Arun Menon906de572013-06-18 17:01:40 -07006350 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006351OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006352 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6353 OMX_IN OMX_U32 port,
6354 OMX_IN OMX_PTR appData,
6355 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006356{
Arun Menon906de572013-06-18 17:01:40 -07006357 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6358 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6359 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006360
6361#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006362 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6363 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006364#else
Arun Menon906de572013-06-18 17:01:40 -07006365 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006366#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006367 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006368 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006369 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006370 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006371#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006372 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006373 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006374 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006375 }
6376 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6377 eglGetProcAddress("eglQueryImageKHR");
6378 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6379 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6380 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006381#else //with OMX test app
6382 struct temp_egl {
6383 int pmem_fd;
6384 int offset;
6385 };
6386 struct temp_egl *temp_egl_id = NULL;
6387 void * pmemPtr = (void *) eglImage;
6388 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006389 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006390 fd = temp_egl_id->pmem_fd;
6391 offset = temp_egl_id->offset;
6392 }
6393#endif
6394 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006395 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006396 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006397 }
6398 pmem_info.pmem_fd = (OMX_U32) fd;
6399 pmem_info.offset = (OMX_U32) offset;
6400 pmem_entry.entry = (void *) &pmem_info;
6401 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6402 pmem_list.entryList = &pmem_entry;
6403 pmem_list.nEntries = 1;
6404 ouput_egl_buffers = true;
6405 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6406 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6407 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006408 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006409 return OMX_ErrorInsufficientResources;
6410 }
6411 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006412}
6413
6414/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006415 FUNCTION
6416 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006417
Arun Menon906de572013-06-18 17:01:40 -07006418 DESCRIPTION
6419 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006420
Arun Menon906de572013-06-18 17:01:40 -07006421 PARAMETERS
6422 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006423
Arun Menon906de572013-06-18 17:01:40 -07006424 RETURN VALUE
6425 OMX Error None if everything is successful.
6426 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006427OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006428 OMX_OUT OMX_U8* role,
6429 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006430{
Arun Menon906de572013-06-18 17:01:40 -07006431 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006432
Arun Menon906de572013-06-18 17:01:40 -07006433 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6434 if ((0 == index) && role) {
6435 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006436 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006437 } else {
6438 eRet = OMX_ErrorNoMore;
6439 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006440 }
Arun Menon906de572013-06-18 17:01:40 -07006441 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6442 if ((0 == index) && role) {
6443 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006444 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006445 } else {
6446 eRet = OMX_ErrorNoMore;
6447 }
6448 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6449 if ((0 == index) && role) {
6450 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006451 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006452 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006453 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006454 eRet = OMX_ErrorNoMore;
6455 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006456 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006457
Arun Menon906de572013-06-18 17:01:40 -07006458 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6459 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6460 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006461
Shalaj Jain273b3e02012-06-22 19:08:03 -07006462 {
Arun Menon906de572013-06-18 17:01:40 -07006463 if ((0 == index) && role) {
6464 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006465 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006466 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006467 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006468 eRet = OMX_ErrorNoMore;
6469 }
6470 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6471 if ((0 == index) && role) {
6472 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006473 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006474 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006475 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006476 eRet = OMX_ErrorNoMore;
6477 }
6478 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6479 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6480 ) {
6481 if ((0 == index) && role) {
6482 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006483 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006484 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006485 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006486 eRet = OMX_ErrorNoMore;
6487 }
6488 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6489 if ((0 == index) && role) {
6490 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006491 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006492 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006493 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006494 eRet = OMX_ErrorNoMore;
6495 }
6496 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006497 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006498 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006499 }
Arun Menon906de572013-06-18 17:01:40 -07006500 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006501}
6502
6503
6504
6505
6506/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006507 FUNCTION
6508 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006509
Arun Menon906de572013-06-18 17:01:40 -07006510 DESCRIPTION
6511 Checks if entire buffer pool is allocated by IL Client or not.
6512 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006513
Arun Menon906de572013-06-18 17:01:40 -07006514 PARAMETERS
6515 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006516
Arun Menon906de572013-06-18 17:01:40 -07006517 RETURN VALUE
6518 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006519
Arun Menon906de572013-06-18 17:01:40 -07006520 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006521bool omx_vdec::allocate_done(void)
6522{
Arun Menon906de572013-06-18 17:01:40 -07006523 bool bRet = false;
6524 bool bRet_In = false;
6525 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006526
Arun Menon906de572013-06-18 17:01:40 -07006527 bRet_In = allocate_input_done();
6528 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006529
Arun Menon906de572013-06-18 17:01:40 -07006530 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006531 bRet = true;
6532 }
Arun Menon906de572013-06-18 17:01:40 -07006533
6534 return bRet;
6535}
6536/* ======================================================================
6537 FUNCTION
6538 omx_vdec::AllocateInputDone
6539
6540 DESCRIPTION
6541 Checks if I/P buffer pool is allocated by IL Client or not.
6542
6543 PARAMETERS
6544 None.
6545
6546 RETURN VALUE
6547 true/false.
6548
6549 ========================================================================== */
6550bool omx_vdec::allocate_input_done(void)
6551{
6552 bool bRet = false;
6553 unsigned i=0;
6554
6555 if (m_inp_mem_ptr == NULL) {
6556 return bRet;
6557 }
6558 if (m_inp_mem_ptr ) {
6559 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6560 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6561 break;
6562 }
6563 }
6564 }
6565 if (i == drv_ctx.ip_buf.actualcount) {
6566 bRet = true;
6567 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6568 }
6569 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6570 m_inp_bPopulated = OMX_TRUE;
6571 }
6572 return bRet;
6573}
6574/* ======================================================================
6575 FUNCTION
6576 omx_vdec::AllocateOutputDone
6577
6578 DESCRIPTION
6579 Checks if entire O/P buffer pool is allocated by IL Client or not.
6580
6581 PARAMETERS
6582 None.
6583
6584 RETURN VALUE
6585 true/false.
6586
6587 ========================================================================== */
6588bool omx_vdec::allocate_output_done(void)
6589{
6590 bool bRet = false;
6591 unsigned j=0;
6592
6593 if (m_out_mem_ptr == NULL) {
6594 return bRet;
6595 }
6596
6597 if (m_out_mem_ptr) {
6598 for (; j < drv_ctx.op_buf.actualcount; j++) {
6599 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6600 break;
6601 }
6602 }
6603 }
6604
6605 if (j == drv_ctx.op_buf.actualcount) {
6606 bRet = true;
6607 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6608 if (m_out_bEnabled)
6609 m_out_bPopulated = OMX_TRUE;
6610 }
6611
6612 return bRet;
6613}
6614
6615/* ======================================================================
6616 FUNCTION
6617 omx_vdec::ReleaseDone
6618
6619 DESCRIPTION
6620 Checks if IL client has released all the buffers.
6621
6622 PARAMETERS
6623 None.
6624
6625 RETURN VALUE
6626 true/false
6627
6628 ========================================================================== */
6629bool omx_vdec::release_done(void)
6630{
6631 bool bRet = false;
6632
6633 if (release_input_done()) {
6634 if (release_output_done()) {
6635 bRet = true;
6636 }
6637 }
6638 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006639}
6640
6641
6642/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006643 FUNCTION
6644 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006645
Arun Menon906de572013-06-18 17:01:40 -07006646 DESCRIPTION
6647 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006648
Arun Menon906de572013-06-18 17:01:40 -07006649 PARAMETERS
6650 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006651
Arun Menon906de572013-06-18 17:01:40 -07006652 RETURN VALUE
6653 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006654
Arun Menon906de572013-06-18 17:01:40 -07006655 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006656bool omx_vdec::release_output_done(void)
6657{
Arun Menon906de572013-06-18 17:01:40 -07006658 bool bRet = false;
6659 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006660
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006661 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006662 if (m_out_mem_ptr) {
6663 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6664 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6665 break;
6666 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006667 }
Arun Menon906de572013-06-18 17:01:40 -07006668 if (j == drv_ctx.op_buf.actualcount) {
6669 m_out_bm_count = 0;
6670 bRet = true;
6671 }
6672 } else {
6673 m_out_bm_count = 0;
6674 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006675 }
Arun Menon906de572013-06-18 17:01:40 -07006676 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006677}
6678/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006679 FUNCTION
6680 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006681
Arun Menon906de572013-06-18 17:01:40 -07006682 DESCRIPTION
6683 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006684
Arun Menon906de572013-06-18 17:01:40 -07006685 PARAMETERS
6686 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006687
Arun Menon906de572013-06-18 17:01:40 -07006688 RETURN VALUE
6689 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006690
Arun Menon906de572013-06-18 17:01:40 -07006691 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006692bool omx_vdec::release_input_done(void)
6693{
Arun Menon906de572013-06-18 17:01:40 -07006694 bool bRet = false;
6695 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006696
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006697 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006698 if (m_inp_mem_ptr) {
6699 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6700 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6701 break;
6702 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006703 }
Arun Menon906de572013-06-18 17:01:40 -07006704 if (j==drv_ctx.ip_buf.actualcount) {
6705 bRet = true;
6706 }
6707 } else {
6708 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006709 }
Arun Menon906de572013-06-18 17:01:40 -07006710 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006711}
6712
6713OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006714 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006715{
Arun Menon906de572013-06-18 17:01:40 -07006716 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306717 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006718 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006719 return OMX_ErrorBadParameter;
6720 } else if (output_flush_progress) {
6721 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6722 buffer->nFilledLen = 0;
6723 buffer->nTimeStamp = 0;
6724 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6725 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6726 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006727 }
6728
Arun Menon906de572013-06-18 17:01:40 -07006729 if (m_debug_extradata) {
6730 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006731 DEBUG_PRINT_HIGH("");
6732 DEBUG_PRINT_HIGH("***************************************************");
6733 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6734 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006735 }
6736
6737 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006738 DEBUG_PRINT_HIGH("");
6739 DEBUG_PRINT_HIGH("***************************************************");
6740 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6741 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006742 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006743 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006744
6745
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006746 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006747 buffer, buffer->pBuffer);
6748 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006749
Arun Menon906de572013-06-18 17:01:40 -07006750 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006751 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006752 if (!output_flush_progress)
6753 post_event((unsigned)NULL, (unsigned)NULL,
6754 OMX_COMPONENT_GENERATE_EOS_DONE);
6755
6756 if (psource_frame) {
6757 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6758 psource_frame = NULL;
6759 }
6760 if (pdest_frame) {
6761 pdest_frame->nFilledLen = 0;
6762 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6763 (unsigned)NULL);
6764 pdest_frame = NULL;
6765 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006766 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006767
Shalaj Jain273b3e02012-06-22 19:08:03 -07006768
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006769 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6770 DEBUG_PRINT_LOW("Processing extradata");
6771 handle_extradata(buffer);
6772 }
6773
Arun Menon906de572013-06-18 17:01:40 -07006774 /* For use buffer we need to copy the data */
6775 if (!output_flush_progress) {
6776 /* This is the error check for non-recoverable errros */
6777 bool is_duplicate_ts_valid = true;
6778 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006779
Arun Menon906de572013-06-18 17:01:40 -07006780 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6781 output_capability == V4L2_PIX_FMT_MPEG2 ||
6782 output_capability == V4L2_PIX_FMT_DIVX ||
6783 output_capability == V4L2_PIX_FMT_DIVX_311)
6784 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006785
Arun Menon906de572013-06-18 17:01:40 -07006786 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
Arun Menon7b6fd642014-02-13 16:48:36 -08006787 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
Arun Menon906de572013-06-18 17:01:40 -07006788 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306789 }
Arun Menon906de572013-06-18 17:01:40 -07006790 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306791
Arun Menon906de572013-06-18 17:01:40 -07006792 if (buffer->nFilledLen > 0) {
6793 time_stamp_dts.get_next_timestamp(buffer,
6794 is_interlaced && is_duplicate_ts_valid);
6795 if (m_debug_timestamp) {
6796 {
6797 OMX_TICKS expected_ts = 0;
6798 m_timestamp_list.pop_min_ts(expected_ts);
6799 if (is_interlaced && is_duplicate_ts_valid) {
6800 m_timestamp_list.pop_min_ts(expected_ts);
6801 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006802 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006803 buffer->nTimeStamp, expected_ts);
6804
6805 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006806 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006807 }
6808 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306809 }
Arun Menon906de572013-06-18 17:01:40 -07006810 } else {
Arun Menon906de572013-06-18 17:01:40 -07006811 time_stamp_dts.remove_time_stamp(
6812 buffer->nTimeStamp,
6813 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306814 }
Arun Menon906de572013-06-18 17:01:40 -07006815
6816
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006817 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006818
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006819 /* Since we're passing around handles, adjust nFilledLen and nAllocLen
6820 * to size of the handle. Do it _after_ handle_extradata() which
6821 * requires the respective sizes to be accurate. */
6822 if (dynamic_buf_mode) {
6823 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
6824 buffer->nFilledLen = buffer->nFilledLen ?
6825 sizeof(struct VideoDecoderOutputMetaData) : 0;
6826 }
6827
Arun Menon906de572013-06-18 17:01:40 -07006828 if (m_cb.FillBufferDone) {
6829 if (buffer->nFilledLen > 0) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006830 if (arbitrary_bytes)
Arun Menon906de572013-06-18 17:01:40 -07006831 adjust_timestamp(buffer->nTimeStamp);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006832 else
6833 set_frame_rate(buffer->nTimeStamp);
6834
Arun Menon906de572013-06-18 17:01:40 -07006835 if (perf_flag) {
6836 if (!proc_frms) {
6837 dec_time.stop();
6838 latency = dec_time.processing_time_us() - latency;
6839 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6840 dec_time.start();
6841 fps_metrics.start();
6842 }
6843 proc_frms++;
6844 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6845 OMX_U64 proc_time = 0;
6846 fps_metrics.stop();
6847 proc_time = fps_metrics.processing_time_us();
6848 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006849 proc_frms, (float)proc_time / 1e6,
6850 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006851 proc_frms = 0;
6852 }
6853 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006854
6855#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006856 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006857
Arun Menon906de572013-06-18 17:01:40 -07006858 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6859 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6860 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6861 buffer->nFilledLen + 3)&(~3));
6862 while (p_extra &&
6863 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006864 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006865 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6866 if (p_extra->eType == OMX_ExtraDataNone) {
6867 break;
6868 }
6869 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6870 }
6871 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006872#endif
Arun Menon906de572013-06-18 17:01:40 -07006873 }
6874 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6875 prev_ts = LLONG_MAX;
6876 rst_prev_ts = true;
6877 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006878
Arun Menon906de572013-06-18 17:01:40 -07006879 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6880 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6881 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006882 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006883 OMX_BUFFERHEADERTYPE *il_buffer;
6884 il_buffer = client_buffers.get_il_buf_hdr(buffer);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006885
vivek mehta79cff222014-01-22 12:17:07 -08006886 if (il_buffer && m_last_rendered_TS >= 0) {
6887 int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
Manikanta Kanamarlapudifb53b262014-01-20 16:12:47 +05306888 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
vivek mehta79cff222014-01-22 12:17:07 -08006889
6890 // Current frame can be send for rendering if
6891 // (a) current FPS is <= 60
6892 // (b) is the next frame after the frame with TS 0
6893 // (c) is the first frame after seek
6894 // (d) the delta TS b\w two consecutive frames is > 16 ms
6895 // (e) its TS is equal to previous frame TS
6896 // (f) if marked EOS
6897
6898 if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
6899 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
6900 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006901 m_last_rendered_TS = il_buffer->nTimeStamp;
vivek mehta79cff222014-01-22 12:17:07 -08006902 } else {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006903 //mark for droping
vivek mehtaa75c69f2014-01-10 21:50:37 -08006904 buffer->nFilledLen = 0;
vivek mehta79cff222014-01-22 12:17:07 -08006905 }
6906
6907 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%d)",
6908 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
6909 il_buffer->nTimeStamp,ts_delta);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006910 }
6911
vivek mehta79cff222014-01-22 12:17:07 -08006912 if (il_buffer) {
Arun Menon9230eb82014-02-11 19:19:02 -08006913 log_output_buffers(il_buffer);
6914 if (dynamic_buf_mode) {
6915 unsigned int nPortIndex = 0;
6916 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6917
6918 if (!secure_mode) {
6919 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6920 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6921 }
6922
6923 //Clear graphic buffer handles in dynamic mode
6924 native_buffer[nPortIndex].privatehandle = NULL;
6925 native_buffer[nPortIndex].nativehandle = NULL;
6926 }
Arun Menon906de572013-06-18 17:01:40 -07006927 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
vivek mehta79cff222014-01-22 12:17:07 -08006928 } else {
Arun Menon906de572013-06-18 17:01:40 -07006929 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6930 return OMX_ErrorBadParameter;
6931 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006932 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006933 } else {
6934 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006935 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006936
Praveen Chavancf924182013-12-06 23:16:23 -08006937#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306938 if (m_smoothstreaming_mode && m_out_mem_ptr) {
Praveen Chavancf924182013-12-06 23:16:23 -08006939 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6940 BufferDim_t dim;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306941 private_handle_t *private_handle = NULL;
Pushkaraj Patil065b5732014-11-26 11:08:02 +05306942 dim.sliceWidth = framesize.nWidth;
6943 dim.sliceHeight = framesize.nHeight;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306944 if (native_buffer[buf_index].privatehandle)
6945 private_handle = native_buffer[buf_index].privatehandle;
Praveen Chavancf924182013-12-06 23:16:23 -08006946 if (private_handle) {
6947 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6948 dim.sliceWidth, dim.sliceHeight);
6949 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6950 }
6951 }
6952#endif
6953
Arun Menon906de572013-06-18 17:01:40 -07006954 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006955}
6956
6957OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006958 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006959{
6960
Surajit Podderd2644d52013-08-28 17:59:06 +05306961 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006962 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006963 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006964 }
6965
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006966 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006967 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006968 pending_input_buffers--;
6969
Arun Menon906de572013-06-18 17:01:40 -07006970 if (arbitrary_bytes) {
6971 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006972 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006973 pdest_frame = buffer;
6974 buffer->nFilledLen = 0;
6975 buffer->nTimeStamp = LLONG_MAX;
6976 push_input_buffer (hComp);
6977 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006978 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006979 buffer->nFilledLen = 0;
6980 if (!m_input_free_q.insert_entry((unsigned)buffer,
6981 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006982 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006983 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006984 }
Arun Menon906de572013-06-18 17:01:40 -07006985 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006986 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006987 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006988 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6989 }
6990 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6991 }
6992 return OMX_ErrorNone;
6993}
6994
Shalaj Jain273b3e02012-06-22 19:08:03 -07006995int omx_vdec::async_message_process (void *context, void* message)
6996{
Arun Menon906de572013-06-18 17:01:40 -07006997 omx_vdec* omx = NULL;
6998 struct vdec_msginfo *vdec_msg = NULL;
6999 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
7000 struct v4l2_buffer *v4l2_buf_ptr = NULL;
7001 struct vdec_output_frameinfo *output_respbuf = NULL;
7002 int rc=1;
7003 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007004 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07007005 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007006 }
Arun Menon906de572013-06-18 17:01:40 -07007007 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007008
Arun Menon906de572013-06-18 17:01:40 -07007009 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07007010
Arun Menon906de572013-06-18 17:01:40 -07007011 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007012
Arun Menon906de572013-06-18 17:01:40 -07007013 case VDEC_MSG_EVT_HW_ERROR:
7014 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7015 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7016 break;
7017
Deepak Verma24720fb2014-01-29 16:57:40 +05307018 case VDEC_MSG_EVT_HW_OVERLOAD:
7019 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7020 OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
7021 break;
7022
Arun Menon906de572013-06-18 17:01:40 -07007023 case VDEC_MSG_RESP_START_DONE:
7024 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7025 OMX_COMPONENT_GENERATE_START_DONE);
7026 break;
7027
7028 case VDEC_MSG_RESP_STOP_DONE:
7029 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7030 OMX_COMPONENT_GENERATE_STOP_DONE);
7031 break;
7032
7033 case VDEC_MSG_RESP_RESUME_DONE:
7034 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7035 OMX_COMPONENT_GENERATE_RESUME_DONE);
7036 break;
7037
7038 case VDEC_MSG_RESP_PAUSE_DONE:
7039 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7040 OMX_COMPONENT_GENERATE_PAUSE_DONE);
7041 break;
7042
7043 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
7044 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7045 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
7046 break;
7047 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
7048 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7049 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
7050 break;
7051 case VDEC_MSG_RESP_INPUT_FLUSHED:
7052 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
7053
7054 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
7055 vdec_msg->msgdata.input_frame_clientdata; */
7056
7057 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
7058 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
7059 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05307060 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07007061 omxhdr = NULL;
7062 vdec_msg->status_code = VDEC_S_EFATAL;
7063 }
7064 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
7065 DEBUG_PRINT_HIGH("Unsupported input");
7066 omx->omx_report_error ();
7067 }
7068 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
7069 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
7070 }
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307071 if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307072
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05307073 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
7074 android_atomic_dec(&omx->m_queued_codec_config_count);
7075 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
7076 BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
7077 DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307078 sem_post(&omx->m_safe_flush);
7079 }
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307080 }
7081
Arun Menon906de572013-06-18 17:01:40 -07007082 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
7083 OMX_COMPONENT_GENERATE_EBD);
7084 break;
7085 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
7086 int64_t *timestamp;
7087 timestamp = (int64_t *) malloc(sizeof(int64_t));
7088 if (timestamp) {
7089 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
7090 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
7091 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007092 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07007093 vdec_msg->msgdata.output_frame.time_stamp);
7094 }
7095 break;
7096 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
7097 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
7098
7099 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
7100 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307101
7102 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 -07007103 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307104 vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
7105 (unsigned int)vdec_msg->msgdata.output_frame.len,
7106 vdec_msg->msgdata.output_frame.framesize.left,
7107 vdec_msg->msgdata.output_frame.framesize.top,
7108 vdec_msg->msgdata.output_frame.framesize.right,
7109 vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07007110
7111 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05307112 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07007113 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05307114 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307115
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07007116 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
Arun Menon906de572013-06-18 17:01:40 -07007117 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
7118 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
7119 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
7120 omxhdr->nFlags = 0;
7121
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07007122 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07007123 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
7124 //rc = -1;
7125 }
7126 if (omxhdr->nFilledLen) {
7127 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
7128 }
7129 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
7130 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
7131 } else {
7132 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
7133 }
7134 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
7135 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7136 }
7137 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
7138 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
7139 }
Arun Menon7b6fd642014-02-13 16:48:36 -08007140
7141 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
7142 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
7143 }
7144
Arun Menonbdb80b02013-08-12 17:45:54 -07007145 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07007146 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07007147 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
7148 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
7149 }
Arun Menonbdb80b02013-08-12 17:45:54 -07007150 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
7151 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
7152 omxhdr->nOffset);
7153 }
Arun Menon906de572013-06-18 17:01:40 -07007154 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
7155 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07007156 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07007157 omx->time_stamp_dts.remove_time_stamp(
7158 omxhdr->nTimeStamp,
7159 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
7160 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07007161 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
7162 OMX_COMPONENT_GENERATE_FTB);
7163 break;
7164 }
7165 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
7166 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7167 }
7168 vdec_msg->msgdata.output_frame.bufferaddr =
7169 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307170
7171 /* Post event if resolution OR crop changed */
7172 /* filled length will be changed if resolution changed */
7173 /* Crop parameters can be changed even without resolution change */
7174 if (omxhdr->nFilledLen
7175 && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
7176 || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
7177 || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
7178 || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05307179 || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
7180 || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
7181 || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307182
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05307183 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",
7184 omx->prev_n_filled_len,
7185 omx->drv_ctx.video_resolution.frame_width,
7186 omx->drv_ctx.video_resolution.frame_height,
7187 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
7188 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
7189 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
7190 vdec_msg->msgdata.output_frame.picsize.frame_height,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307191 vdec_msg->msgdata.output_frame.framesize.left,
7192 vdec_msg->msgdata.output_frame.framesize.top,
7193 vdec_msg->msgdata.output_frame.framesize.right,
7194 vdec_msg->msgdata.output_frame.framesize.bottom);
7195
Maheshwar Ajja0f840ce2014-09-29 16:53:42 +05307196 omx->drv_ctx.video_resolution.frame_width =
7197 vdec_msg->msgdata.output_frame.picsize.frame_width;
7198 omx->drv_ctx.video_resolution.frame_height =
7199 vdec_msg->msgdata.output_frame.picsize.frame_height;
Praneeth Paladuguca80be72014-10-22 23:48:54 -07007200 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
7201 omx->drv_ctx.video_resolution.stride =
7202 VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
7203 omx->drv_ctx.video_resolution.scan_lines =
7204 VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
7205 }
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307206 memcpy(&omx->drv_ctx.frame_size,
7207 &vdec_msg->msgdata.output_frame.framesize,
7208 sizeof(struct vdec_framesize));
7209
7210 omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
7211 OMX_IndexConfigCommonOutputCrop,
7212 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Arun Menon906de572013-06-18 17:01:40 -07007213 }
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307214
Arun Menon906de572013-06-18 17:01:40 -07007215 if (omxhdr->nFilledLen)
7216 omx->prev_n_filled_len = omxhdr->nFilledLen;
7217
7218 output_respbuf = (struct vdec_output_frameinfo *)\
7219 omxhdr->pOutputPortPrivate;
7220 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7221 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307222
Arun Menon906de572013-06-18 17:01:40 -07007223 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
7224 output_respbuf->pic_type = PICTURE_TYPE_I;
7225 }
7226 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
7227 output_respbuf->pic_type = PICTURE_TYPE_P;
7228 }
7229 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7230 output_respbuf->pic_type = PICTURE_TYPE_B;
7231 }
7232
7233 if (omx->output_use_buffer)
7234 memcpy ( omxhdr->pBuffer, (void *)
7235 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7236 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7237 vdec_msg->msgdata.output_frame.len);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307238 } else {
7239 DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
7240 (unsigned int)vdec_msg->msgdata.output_frame.len,
7241 omxhdr->nAllocLen, omx->prev_n_filled_len);
Arun Menon906de572013-06-18 17:01:40 -07007242 omxhdr->nFilledLen = 0;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307243 }
7244
Arun Menon906de572013-06-18 17:01:40 -07007245 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7246 OMX_COMPONENT_GENERATE_FBD);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307247
7248 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07007249 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7250 OMX_COMPONENT_GENERATE_EOS_DONE);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307251 } else {
Arun Menon906de572013-06-18 17:01:40 -07007252 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7253 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307254 }
Arun Menon906de572013-06-18 17:01:40 -07007255 break;
7256 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007257 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07007258 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7259 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7260 break;
7261 default:
7262 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007263 }
Arun Menon906de572013-06-18 17:01:40 -07007264 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007265}
7266
7267OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07007268 OMX_HANDLETYPE hComp,
7269 OMX_BUFFERHEADERTYPE *buffer
7270 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07007271{
Arun Menon906de572013-06-18 17:01:40 -07007272 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007273 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007274
Arun Menon906de572013-06-18 17:01:40 -07007275 if (buffer == NULL) {
7276 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007277 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007278 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7279 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007280 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
7281
7282 /* return zero length and not an EOS buffer */
7283 /* return buffer if input flush in progress */
7284 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7285 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007286 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07007287 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7288 return OMX_ErrorNone;
7289 }
7290
7291 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007292 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007293 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007294 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07007295 push_input_buffer (hComp);
7296 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007297 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07007298 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7299 (unsigned)NULL)) {
7300 return OMX_ErrorBadParameter;
7301 }
7302 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007303
Sowmya Pandiri302f5ab2014-04-03 13:41:03 -07007304 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
7305 codec_config_flag = false;
7306 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007307
Arun Menon906de572013-06-18 17:01:40 -07007308 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007309}
7310
7311OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7312{
Arun Menon906de572013-06-18 17:01:40 -07007313 unsigned address,p2,id;
7314 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007315
Arun Menon906de572013-06-18 17:01:40 -07007316 if (pdest_frame == NULL || psource_frame == NULL) {
7317 /*Check if we have a destination buffer*/
7318 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007319 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007320 if (m_input_free_q.m_size) {
7321 m_input_free_q.pop_entry(&address,&p2,&id);
7322 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7323 pdest_frame->nFilledLen = 0;
7324 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007325 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007326 }
7327 }
7328
7329 /*Check if we have a destination buffer*/
7330 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007331 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007332 if (m_input_pending_q.m_size) {
7333 m_input_pending_q.pop_entry(&address,&p2,&id);
7334 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007335 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007336 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007337 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007338 psource_frame->nFlags,psource_frame->nFilledLen);
7339
7340 }
7341 }
7342
Shalaj Jain273b3e02012-06-22 19:08:03 -07007343 }
7344
Arun Menon906de572013-06-18 17:01:40 -07007345 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7346 switch (codec_type_parse) {
7347 case CODEC_TYPE_MPEG4:
7348 case CODEC_TYPE_H263:
7349 case CODEC_TYPE_MPEG2:
7350 ret = push_input_sc_codec(hComp);
7351 break;
7352 case CODEC_TYPE_H264:
7353 ret = push_input_h264(hComp);
7354 break;
7355 case CODEC_TYPE_VC1:
7356 ret = push_input_vc1(hComp);
7357 break;
7358 default:
7359 break;
7360 }
7361 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007362 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007363 omx_report_error ();
7364 break;
7365 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007366 }
7367
Arun Menon906de572013-06-18 17:01:40 -07007368 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007369}
7370
7371OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7372{
Arun Menon906de572013-06-18 17:01:40 -07007373 OMX_U32 partial_frame = 1;
7374 OMX_BOOL generate_ebd = OMX_TRUE;
7375 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007376
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007377 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007378 psource_frame,psource_frame->nTimeStamp);
7379 if (m_frame_parser.parse_sc_frame(psource_frame,
7380 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007381 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007382 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007383 }
Arun Menon906de572013-06-18 17:01:40 -07007384
7385 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007386 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007387 pdest_frame->nFilledLen,psource_frame,frame_count);
7388
7389
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007390 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007391 /*First Parsed buffer will have only header Hence skip*/
7392 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007393 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007394
7395 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7396 codec_type_parse == CODEC_TYPE_DIVX) {
7397 mp4StreamType psBits;
7398 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7399 psBits.numBytes = pdest_frame->nFilledLen;
7400 mp4_headerparser.parseHeader(&psBits);
7401 }
7402
7403 frame_count++;
7404 } else {
7405 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7406 if (pdest_frame->nFilledLen) {
7407 /*Push the frame to the Decoder*/
7408 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7409 return OMX_ErrorBadParameter;
7410 }
7411 frame_count++;
7412 pdest_frame = NULL;
7413
7414 if (m_input_free_q.m_size) {
7415 m_input_free_q.pop_entry(&address,&p2,&id);
7416 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7417 pdest_frame->nFilledLen = 0;
7418 }
7419 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007420 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007421 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7422 (unsigned)NULL);
7423 pdest_frame = NULL;
7424 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007425 }
Arun Menon906de572013-06-18 17:01:40 -07007426 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007427 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007428 /*Check if Destination Buffer is full*/
7429 if (pdest_frame->nAllocLen ==
7430 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007431 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007432 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007433 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007434 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007435
Arun Menon906de572013-06-18 17:01:40 -07007436 if (psource_frame->nFilledLen == 0) {
7437 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7438 if (pdest_frame) {
7439 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007440 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007441 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007442 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007443 pdest_frame->nFilledLen,frame_count++);
7444 /*Push the frame to the Decoder*/
7445 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7446 return OMX_ErrorBadParameter;
7447 }
7448 frame_count++;
7449 pdest_frame = NULL;
7450 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007451 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007452 generate_ebd = OMX_FALSE;
7453 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007454 }
Arun Menon906de572013-06-18 17:01:40 -07007455 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007456 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007457 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7458 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007459
Arun Menon906de572013-06-18 17:01:40 -07007460 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007461 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007462 m_input_pending_q.pop_entry(&address,&p2,&id);
7463 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007464 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007465 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007466 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007467 psource_frame->nFlags,psource_frame->nFilledLen);
7468 }
7469 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007470 }
Arun Menon906de572013-06-18 17:01:40 -07007471 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007472}
7473
7474OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7475{
Arun Menon906de572013-06-18 17:01:40 -07007476 OMX_U32 partial_frame = 1;
7477 unsigned address = 0, p2 = 0, id = 0;
7478 OMX_BOOL isNewFrame = OMX_FALSE;
7479 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007480
Arun Menon906de572013-06-18 17:01:40 -07007481 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007482 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007483 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007484 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007485 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007486 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007487 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007488 if (h264_scratch.nFilledLen && look_ahead_nal) {
7489 look_ahead_nal = false;
7490 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7491 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007492 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7493 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7494 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007495 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007496 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007497 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007498 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007499 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007500 }
Arun Menon906de572013-06-18 17:01:40 -07007501 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007502
7503 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7504 in EOS flag getting associated with the destination
7505 */
7506 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7507 pdest_frame->nFilledLen) {
7508 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7509 generate_ebd = OMX_FALSE;
7510 }
7511
Arun Menon906de572013-06-18 17:01:40 -07007512 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007513 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007514 if (m_frame_parser.parse_sc_frame(psource_frame,
7515 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007516 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007517 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007518 }
Arun Menon906de572013-06-18 17:01:40 -07007519 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007520 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007521 if (m_frame_parser.parse_h264_nallength(psource_frame,
7522 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007523 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007524 return OMX_ErrorBadParameter;
7525 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007526 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007527
Arun Menon906de572013-06-18 17:01:40 -07007528 if (partial_frame == 0) {
7529 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007530 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007531 nal_count++;
7532 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7533 h264_scratch.nFlags = psource_frame->nFlags;
7534 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007535 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007536 if (h264_scratch.nFilledLen) {
7537 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7538 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007539#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007540 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7541 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7542 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7543 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7544 // If timeinfo is present frame info from SEI is already processed
7545 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7546 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007547#endif
Arun Menon906de572013-06-18 17:01:40 -07007548 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7549 nal_count++;
7550 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7551 pdest_frame->nTimeStamp = h264_last_au_ts;
7552 pdest_frame->nFlags = h264_last_au_flags;
7553#ifdef PANSCAN_HDLR
7554 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7555 h264_parser->update_panscan_data(h264_last_au_ts);
7556#endif
7557 }
7558 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7559 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7560 h264_last_au_ts = h264_scratch.nTimeStamp;
7561 h264_last_au_flags = h264_scratch.nFlags;
7562#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7563 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7564 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7565 if (!VALID_TS(h264_last_au_ts))
7566 h264_last_au_ts = ts_in_sei;
7567 }
7568#endif
7569 } else
7570 h264_last_au_ts = LLONG_MAX;
7571 }
7572
7573 if (!isNewFrame) {
7574 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7575 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007576 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007577 h264_scratch.nFilledLen);
7578 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7579 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7580 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7581 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7582 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7583 h264_scratch.nFilledLen = 0;
7584 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007585 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007586 return OMX_ErrorBadParameter;
7587 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007588 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007589 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007590 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007591 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007592 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007593 pdest_frame->nFilledLen,frame_count++);
7594
7595 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007596 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007597 look_ahead_nal = false;
7598 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7599 h264_scratch.nFilledLen) {
7600 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7601 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7602 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7603 h264_scratch.nFilledLen = 0;
7604 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007605 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007606 return OMX_ErrorBadParameter;
7607 }
7608 } else {
7609 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007610 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007611 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7612 }
7613 /*Push the frame to the Decoder*/
7614 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7615 return OMX_ErrorBadParameter;
7616 }
7617 //frame_count++;
7618 pdest_frame = NULL;
7619 if (m_input_free_q.m_size) {
7620 m_input_free_q.pop_entry(&address,&p2,&id);
7621 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007622 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007623 pdest_frame->nFilledLen = 0;
7624 pdest_frame->nFlags = 0;
7625 pdest_frame->nTimeStamp = LLONG_MAX;
7626 }
7627 }
7628 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007629 }
Arun Menon906de572013-06-18 17:01:40 -07007630 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007631 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007632 /*Check if Destination Buffer is full*/
7633 if (h264_scratch.nAllocLen ==
7634 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007635 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007636 return OMX_ErrorStreamCorrupt;
7637 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007638 }
Arun Menon906de572013-06-18 17:01:40 -07007639
7640 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007641 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007642
7643 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7644 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007645 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007646 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7647 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007648 if(pdest_frame->nFilledLen == 0) {
7649 /* No residual frame from before, send whatever
7650 * we have left */
7651 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7652 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7653 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7654 h264_scratch.nFilledLen = 0;
7655 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7656 } else {
7657 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7658 if(!isNewFrame) {
7659 /* Have a residual frame, but we know that the
7660 * AU in this frame is belonging to whatever
7661 * frame we had left over. So append it */
7662 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7663 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7664 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7665 h264_scratch.nFilledLen = 0;
Balamurugan Alagarsamyefde3832014-09-22 19:52:20 +05307666 if (h264_last_au_ts != LLONG_MAX)
7667 pdest_frame->nTimeStamp = h264_last_au_ts;
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007668 } else {
7669 /* Completely new frame, let's just push what
7670 * we have now. The resulting EBD would trigger
7671 * another push */
7672 generate_ebd = OMX_FALSE;
7673 pdest_frame->nTimeStamp = h264_last_au_ts;
7674 h264_last_au_ts = h264_scratch.nTimeStamp;
7675 }
7676 }
Arun Menon906de572013-06-18 17:01:40 -07007677 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007678 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007679 return OMX_ErrorBadParameter;
7680 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007681
7682 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7683 if(generate_ebd == OMX_TRUE) {
7684 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7685 }
Arun Menon906de572013-06-18 17:01:40 -07007686
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007687 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007688 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007689 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007690#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7691 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7692 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7693 if (!VALID_TS(pdest_frame->nTimeStamp))
7694 pdest_frame->nTimeStamp = ts_in_sei;
7695 }
7696#endif
7697 /*Push the frame to the Decoder*/
7698 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7699 return OMX_ErrorBadParameter;
7700 }
7701 frame_count++;
7702 pdest_frame = NULL;
7703 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007704 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007705 pdest_frame,h264_scratch.nFilledLen);
7706 generate_ebd = OMX_FALSE;
7707 }
7708 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007709 }
Arun Menon906de572013-06-18 17:01:40 -07007710 if (generate_ebd && !psource_frame->nFilledLen) {
7711 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7712 psource_frame = NULL;
7713 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007714 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007715 m_input_pending_q.pop_entry(&address,&p2,&id);
7716 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007717 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007718 psource_frame->nFlags,psource_frame->nFilledLen);
7719 }
7720 }
7721 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007722}
7723
7724OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7725{
7726 OMX_U8 *buf, *pdest;
7727 OMX_U32 partial_frame = 1;
7728 OMX_U32 buf_len, dest_len;
7729
Arun Menon906de572013-06-18 17:01:40 -07007730 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007731 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007732 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007733 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007734 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007735 buf = psource_frame->pBuffer;
7736 buf_len = psource_frame->nFilledLen;
7737
7738 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007739 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007740 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007741 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007742 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007743 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007744 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007745 return OMX_ErrorStreamCorrupt;
7746 }
Arun Menon906de572013-06-18 17:01:40 -07007747 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007748 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7749 pdest_frame->nOffset;
7750 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007751 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007752
Arun Menon906de572013-06-18 17:01:40 -07007753 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007754 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007755 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007756 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007757 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7758 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7759 }
7760 }
7761 }
7762
Arun Menon906de572013-06-18 17:01:40 -07007763 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007764 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007765 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007766 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007767 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007768 return OMX_ErrorBadParameter;
7769 }
Arun Menon906de572013-06-18 17:01:40 -07007770 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007771
7772 case VC1_SP_MP_RCV:
7773 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007774 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007775 return OMX_ErrorBadParameter;
7776 }
7777 return OMX_ErrorNone;
7778}
7779
David Ng38e2d232013-03-15 20:05:58 -07007780#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007781bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007782 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007783{
Arun Menon906de572013-06-18 17:01:40 -07007784 struct pmem_allocation allocation;
7785 allocation.size = buffer_size;
7786 allocation.align = clip2(alignment);
7787 if (allocation.align < 4096) {
7788 allocation.align = 4096;
7789 }
7790 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007791 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007792 allocation.align, allocation.size);
7793 return false;
7794 }
7795 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007796}
David Ng38e2d232013-03-15 20:05:58 -07007797#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007798#ifdef USE_ION
7799int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007800 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7801 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007802{
Arun Menon906de572013-06-18 17:01:40 -07007803 int fd = -EINVAL;
7804 int rc = -EINVAL;
7805 int ion_dev_flag;
7806 struct vdec_ion ion_buf_info;
7807 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007808 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007809 return -EINVAL;
7810 }
7811 ion_dev_flag = O_RDONLY;
7812 fd = open (MEM_DEVICE, ion_dev_flag);
7813 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007814 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007815 return fd;
7816 }
7817 alloc_data->flags = 0;
7818 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7819 alloc_data->flags |= ION_FLAG_CACHED;
7820 }
7821 alloc_data->len = buffer_size;
7822 alloc_data->align = clip2(alignment);
7823 if (alloc_data->align < 4096) {
7824 alloc_data->align = 4096;
7825 }
7826 if ((secure_mode) && (flag & ION_SECURE))
7827 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007828
Arun Menon906de572013-06-18 17:01:40 -07007829 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307830 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007831 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7832 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7833 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007834 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007835 alloc_data->handle = NULL;
7836 close(fd);
7837 fd = -ENOMEM;
7838 return fd;
7839 }
7840 fd_data->handle = alloc_data->handle;
7841 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7842 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007843 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007844 ion_buf_info.ion_alloc_data = *alloc_data;
7845 ion_buf_info.ion_device_fd = fd;
7846 ion_buf_info.fd_ion_data = *fd_data;
7847 free_ion_memory(&ion_buf_info);
7848 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007849 fd = -ENOMEM;
7850 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007851
Arun Menon906de572013-06-18 17:01:40 -07007852 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007853}
7854
Arun Menon906de572013-06-18 17:01:40 -07007855void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7856{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007857
Arun Menon906de572013-06-18 17:01:40 -07007858 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007859 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007860 return;
7861 }
7862 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7863 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007864 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007865 }
7866 close(buf_ion_info->ion_device_fd);
7867 buf_ion_info->ion_device_fd = -1;
7868 buf_ion_info->ion_alloc_data.handle = NULL;
7869 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007870}
7871#endif
7872void omx_vdec::free_output_buffer_header()
7873{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007874 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007875 output_use_buffer = false;
7876 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007877
Arun Menon906de572013-06-18 17:01:40 -07007878 if (m_out_mem_ptr) {
7879 free (m_out_mem_ptr);
7880 m_out_mem_ptr = NULL;
7881 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007882
Arun Menon906de572013-06-18 17:01:40 -07007883 if (m_platform_list) {
7884 free(m_platform_list);
7885 m_platform_list = NULL;
7886 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007887
Arun Menon906de572013-06-18 17:01:40 -07007888 if (drv_ctx.ptr_respbuffer) {
7889 free (drv_ctx.ptr_respbuffer);
7890 drv_ctx.ptr_respbuffer = NULL;
7891 }
7892 if (drv_ctx.ptr_outputbuffer) {
7893 free (drv_ctx.ptr_outputbuffer);
7894 drv_ctx.ptr_outputbuffer = NULL;
7895 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007896#ifdef USE_ION
7897 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007898 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007899 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007900 drv_ctx.op_buf_ion_info = NULL;
7901 }
7902#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007903 if (out_dynamic_list) {
7904 free(out_dynamic_list);
7905 out_dynamic_list = NULL;
7906 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007907}
7908
7909void omx_vdec::free_input_buffer_header()
7910{
7911 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007912 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007913 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007914 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007915 free (m_inp_heap_ptr);
7916 m_inp_heap_ptr = NULL;
7917 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007918
Arun Menon906de572013-06-18 17:01:40 -07007919 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007920 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007921 free (m_phdr_pmem_ptr);
7922 m_phdr_pmem_ptr = NULL;
7923 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007924 }
Arun Menon906de572013-06-18 17:01:40 -07007925 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007926 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007927 free (m_inp_mem_ptr);
7928 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007929 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007930 /* We just freed all the buffer headers, every thing in m_input_free_q,
7931 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007932 while (m_input_free_q.m_size) {
7933 unsigned address, p2, id;
7934 m_input_free_q.pop_entry(&address, &p2, &id);
7935 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007936 while (m_input_pending_q.m_size) {
7937 unsigned address, p2, id;
7938 m_input_pending_q.pop_entry(&address, &p2, &id);
7939 }
7940 pdest_frame = NULL;
7941 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007942 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007943 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007944 free (drv_ctx.ptr_inputbuffer);
7945 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007946 }
7947#ifdef USE_ION
7948 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007949 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007950 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007951 drv_ctx.ip_buf_ion_info = NULL;
7952 }
7953#endif
7954}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007955
7956int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007957{
Arun Menon906de572013-06-18 17:01:40 -07007958 enum v4l2_buf_type btype;
7959 int rc = 0;
7960 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007961
Arun Menon906de572013-06-18 17:01:40 -07007962 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7963 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7964 v4l2_port = OUTPUT_PORT;
7965 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7966 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7967 v4l2_port = CAPTURE_PORT;
7968 } else if (port == OMX_ALL) {
7969 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7970 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007971
Arun Menon906de572013-06-18 17:01:40 -07007972 if (!rc_input)
7973 return rc_input;
7974 else
7975 return rc_output;
7976 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007977
Arun Menon906de572013-06-18 17:01:40 -07007978 if (!streaming[v4l2_port]) {
7979 // already streamed off, warn and move on
7980 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7981 " which is already streamed off", v4l2_port);
7982 return 0;
7983 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007984
Arun Menon906de572013-06-18 17:01:40 -07007985 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007986
Arun Menon906de572013-06-18 17:01:40 -07007987 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7988 if (rc) {
7989 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007990 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007991 } else {
7992 streaming[v4l2_port] = false;
7993 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007994
Arun Menon906de572013-06-18 17:01:40 -07007995 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007996}
7997
7998OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7999{
Arun Menon906de572013-06-18 17:01:40 -07008000 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8001 struct v4l2_requestbuffers bufreq;
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07008002 unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308003 unsigned int final_extra_data_size = 0;
Arun Menon906de572013-06-18 17:01:40 -07008004 struct v4l2_format fmt;
8005 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008006 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008007 buffer_prop->actualcount, buffer_prop->buffer_size);
8008 bufreq.memory = V4L2_MEMORY_USERPTR;
8009 bufreq.count = 1;
8010 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8011 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8012 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8013 fmt.fmt.pix_mp.pixelformat = output_capability;
8014 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8015 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8016 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8017 fmt.fmt.pix_mp.pixelformat = capture_capability;
8018 } else {
8019 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008020 }
Arun Menon906de572013-06-18 17:01:40 -07008021 if (eRet==OMX_ErrorNone) {
8022 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008023 }
Arun Menon906de572013-06-18 17:01:40 -07008024 if (ret) {
8025 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8026 /*TODO: How to handle this case */
8027 eRet = OMX_ErrorInsufficientResources;
8028 return eRet;
8029 } else {
8030 buffer_prop->actualcount = bufreq.count;
8031 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008032 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008033 }
Arun Menon906de572013-06-18 17:01:40 -07008034 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
8035 buffer_prop->actualcount, buffer_prop->buffer_size);
8036
8037 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8038 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
8039
8040 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8041
8042 update_resolution(fmt.fmt.pix_mp.width,
8043 fmt.fmt.pix_mp.height,
8044 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
8045 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
8046 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
8047 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008048 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07008049
8050 if (ret) {
8051 /*TODO: How to handle this case */
8052 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8053 eRet = OMX_ErrorInsufficientResources;
8054 } else {
8055 int extra_idx = 0;
8056
8057 eRet = is_video_session_supported();
8058 if (eRet)
8059 return eRet;
8060
8061 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
8062 buf_size = buffer_prop->buffer_size;
8063 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
8064 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
8065 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
8066 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008067 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07008068 return OMX_ErrorBadParameter;
8069 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008070
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07008071 default_extra_data_size = VENUS_EXTRADATA_SIZE(
8072 drv_ctx.video_resolution.frame_height,
8073 drv_ctx.video_resolution.frame_width);
8074 final_extra_data_size = extra_data_size > default_extra_data_size ?
8075 extra_data_size : default_extra_data_size;
8076
8077 final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
8078 (~(buffer_prop->alignment - 1));
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07008079
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308080 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07008081 drv_ctx.extradata_info.count = buffer_prop->actualcount;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308082 drv_ctx.extradata_info.buffer_size = final_extra_data_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308083 if (!secure_mode)
8084 buf_size += final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07008085 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8086 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
8087 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008088 if (extra_data_size)
8089 DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%d)",
8090 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
8091
Arun Menon906de572013-06-18 17:01:40 -07008092 if (in_reconfig) // BufReq will be set to driver when port is disabled
8093 buffer_prop->buffer_size = buf_size;
8094 else if (buf_size != buffer_prop->buffer_size) {
8095 buffer_prop->buffer_size = buf_size;
8096 eRet = set_buffer_req(buffer_prop);
8097 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008098 }
Arun Menon906de572013-06-18 17:01:40 -07008099 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
8100 buffer_prop->actualcount, buffer_prop->buffer_size);
8101 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008102}
8103
8104OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
8105{
Arun Menon906de572013-06-18 17:01:40 -07008106 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8107 unsigned buf_size = 0;
8108 struct v4l2_format fmt;
8109 struct v4l2_requestbuffers bufreq;
8110 int ret;
8111 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
8112 buffer_prop->actualcount, buffer_prop->buffer_size);
8113 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8114 if (buf_size != buffer_prop->buffer_size) {
8115 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
8116 buffer_prop->buffer_size, buf_size);
8117 eRet = OMX_ErrorBadParameter;
8118 } else {
8119 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8120 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008121
Arun Menon906de572013-06-18 17:01:40 -07008122 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8123 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8124 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07008125 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07008126 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8127 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8128 fmt.fmt.pix_mp.pixelformat = capture_capability;
8129 } else {
8130 eRet = OMX_ErrorBadParameter;
8131 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008132
Arun Menon906de572013-06-18 17:01:40 -07008133 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
8134 if (ret) {
8135 /*TODO: How to handle this case */
8136 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
8137 eRet = OMX_ErrorInsufficientResources;
8138 }
8139
8140 bufreq.memory = V4L2_MEMORY_USERPTR;
8141 bufreq.count = buffer_prop->actualcount;
8142 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8143 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8144 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8145 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8146 } else {
8147 eRet = OMX_ErrorBadParameter;
8148 }
8149
8150 if (eRet==OMX_ErrorNone) {
8151 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8152 }
8153
8154 if (ret) {
8155 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8156 /*TODO: How to handle this case */
8157 eRet = OMX_ErrorInsufficientResources;
8158 } else if (bufreq.count < buffer_prop->actualcount) {
8159 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8160 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8161 buffer_prop->actualcount, bufreq.count);
8162 eRet = OMX_ErrorInsufficientResources;
8163 } else {
8164 if (!client_buffers.update_buffer_req()) {
8165 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8166 eRet = OMX_ErrorInsufficientResources;
8167 }
8168 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008169 }
Arun Menon906de572013-06-18 17:01:40 -07008170 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008171}
8172
Shalaj Jain273b3e02012-06-22 19:08:03 -07008173OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8174{
Arun Menon906de572013-06-18 17:01:40 -07008175 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8176 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008177}
8178
8179OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8180{
Arun Menon906de572013-06-18 17:01:40 -07008181 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308182 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07008183 if (!portDefn) {
8184 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008185 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008186 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07008187 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8188 portDefn->nSize = sizeof(portDefn);
8189 portDefn->eDomain = OMX_PortDomainVideo;
8190 if (drv_ctx.frame_rate.fps_denominator > 0)
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08008191 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
8192 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
Arun Menon906de572013-06-18 17:01:40 -07008193 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008194 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07008195 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008196 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308197 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Arun Menon906de572013-06-18 17:01:40 -07008198 if (0 == portDefn->nPortIndex) {
8199 portDefn->eDir = OMX_DirInput;
8200 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8201 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8202 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8203 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8204 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8205 portDefn->bEnabled = m_inp_bEnabled;
8206 portDefn->bPopulated = m_inp_bPopulated;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308207
8208 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8209 fmt.fmt.pix_mp.pixelformat = output_capability;
Arun Menon906de572013-06-18 17:01:40 -07008210 } else if (1 == portDefn->nPortIndex) {
8211 unsigned int buf_size = 0;
8212 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008213 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07008214 return OMX_ErrorHardware;
8215 }
8216 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008217 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07008218 return OMX_ErrorHardware;
8219 }
8220 portDefn->nBufferSize = buf_size;
8221 portDefn->eDir = OMX_DirOutput;
8222 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8223 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
8224 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8225 portDefn->bEnabled = m_out_bEnabled;
8226 portDefn->bPopulated = m_out_bPopulated;
8227 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008228 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07008229 return OMX_ErrorHardware;
8230 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308231 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8232 fmt.fmt.pix_mp.pixelformat = capture_capability;
Arun Menon906de572013-06-18 17:01:40 -07008233 } else {
8234 portDefn->eDir = OMX_DirMax;
8235 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8236 (int)portDefn->nPortIndex);
8237 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008238 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308239 if (is_down_scalar_enabled) {
8240 int ret = 0;
8241 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8242 if (ret) {
8243 DEBUG_PRINT_ERROR("update_portdef : Error in getting port resolution");
8244 return OMX_ErrorHardware;
8245 } else {
8246 portDefn->format.video.nFrameWidth = fmt.fmt.pix_mp.width;
8247 portDefn->format.video.nFrameHeight = fmt.fmt.pix_mp.height;
8248 portDefn->format.video.nStride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
8249 portDefn->format.video.nSliceHeight = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
8250 }
8251 } else {
8252 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8253 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8254 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8255 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
8256 }
8257
Praveen Chavandb7776f2014-02-06 18:17:25 -08008258 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
8259 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308260 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
8261 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
8262 }
8263 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
8264 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
8265 portDefn->nPortIndex,
8266 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07008267 portDefn->format.video.nFrameHeight,
8268 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308269 portDefn->format.video.nSliceHeight,
8270 portDefn->format.video.eColorFormat,
8271 portDefn->nBufferSize,
8272 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008273
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308274 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008275}
8276
8277OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8278{
Arun Menon906de572013-06-18 17:01:40 -07008279 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8280 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8281 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008282
Arun Menon906de572013-06-18 17:01:40 -07008283 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008284 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07008285 int nBufHdrSize = 0;
8286 int nPlatformEntrySize = 0;
8287 int nPlatformListSize = 0;
8288 int nPMEMInfoSize = 0;
8289 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8290 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8291 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008292
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008293 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008294 drv_ctx.op_buf.actualcount);
8295 nBufHdrSize = drv_ctx.op_buf.actualcount *
8296 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008297
Arun Menon906de572013-06-18 17:01:40 -07008298 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8299 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8300 nPlatformListSize = drv_ctx.op_buf.actualcount *
8301 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8302 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8303 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008304
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008305 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07008306 sizeof(OMX_BUFFERHEADERTYPE),
8307 nPMEMInfoSize,
8308 nPlatformListSize);
Deva Ramasubramanianeb819322014-07-17 14:23:35 -07008309 DEBUG_PRINT_LOW("PE %d bmSize %"PRId64, nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07008310 m_out_bm_count);
8311 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8312 // Alloc mem for platform specific info
8313 char *pPtr=NULL;
8314 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8315 nPMEMInfoSize,1);
8316 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8317 calloc (sizeof(struct vdec_bufferpayload),
8318 drv_ctx.op_buf.actualcount);
8319 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8320 calloc (sizeof (struct vdec_output_frameinfo),
8321 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008322 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
8323 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
8324 return OMX_ErrorInsufficientResources;
8325 }
8326
Shalaj Jain273b3e02012-06-22 19:08:03 -07008327#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008328 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8329 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008330 if (!drv_ctx.op_buf_ion_info) {
8331 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
8332 return OMX_ErrorInsufficientResources;
8333 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008334#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07008335 if (dynamic_buf_mode) {
8336 out_dynamic_list = (struct dynamic_buf_list *) \
8337 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
8338 }
Arun Menon906de572013-06-18 17:01:40 -07008339 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8340 && drv_ctx.ptr_respbuffer) {
8341 bufHdr = m_out_mem_ptr;
8342 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8343 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8344 (((char *) m_platform_list) + nPlatformListSize);
8345 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8346 (((char *) m_platform_entry) + nPlatformEntrySize);
8347 pPlatformList = m_platform_list;
8348 pPlatformEntry = m_platform_entry;
8349 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008350
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008351 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008352
Arun Menon906de572013-06-18 17:01:40 -07008353 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008354 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07008355 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008356 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07008357 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
8358 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8359 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8360 // Set the values when we determine the right HxW param
8361 bufHdr->nAllocLen = 0;
8362 bufHdr->nFilledLen = 0;
8363 bufHdr->pAppPrivate = NULL;
8364 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8365 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8366 pPlatformEntry->entry = pPMEMInfo;
8367 // Initialize the Platform List
8368 pPlatformList->nEntries = 1;
8369 pPlatformList->entryList = pPlatformEntry;
8370 // Keep pBuffer NULL till vdec is opened
8371 bufHdr->pBuffer = NULL;
8372 pPMEMInfo->offset = 0;
8373 pPMEMInfo->pmem_fd = 0;
8374 bufHdr->pPlatformPrivate = pPlatformList;
8375 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008376#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008377 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008378#endif
Arun Menon906de572013-06-18 17:01:40 -07008379 /*Create a mapping between buffers*/
8380 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8381 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8382 &drv_ctx.ptr_outputbuffer[i];
8383 // Move the buffer and buffer header pointers
8384 bufHdr++;
8385 pPMEMInfo++;
8386 pPlatformEntry++;
8387 pPlatformList++;
8388 }
8389 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008390 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008391 m_out_mem_ptr, pPtr);
8392 if (m_out_mem_ptr) {
8393 free(m_out_mem_ptr);
8394 m_out_mem_ptr = NULL;
8395 }
8396 if (pPtr) {
8397 free(pPtr);
8398 pPtr = NULL;
8399 }
8400 if (drv_ctx.ptr_outputbuffer) {
8401 free(drv_ctx.ptr_outputbuffer);
8402 drv_ctx.ptr_outputbuffer = NULL;
8403 }
8404 if (drv_ctx.ptr_respbuffer) {
8405 free(drv_ctx.ptr_respbuffer);
8406 drv_ctx.ptr_respbuffer = NULL;
8407 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008408#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008409 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008410 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008411 free(drv_ctx.op_buf_ion_info);
8412 drv_ctx.op_buf_ion_info = NULL;
8413 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008414#endif
Arun Menon906de572013-06-18 17:01:40 -07008415 eRet = OMX_ErrorInsufficientResources;
8416 }
8417 } else {
8418 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008419 }
Arun Menon906de572013-06-18 17:01:40 -07008420 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008421}
8422
8423void omx_vdec::complete_pending_buffer_done_cbs()
8424{
Arun Menon906de572013-06-18 17:01:40 -07008425 unsigned p1;
8426 unsigned p2;
8427 unsigned ident;
8428 omx_cmd_queue tmp_q, pending_bd_q;
8429 pthread_mutex_lock(&m_lock);
8430 // pop all pending GENERATE FDB from ftb queue
8431 while (m_ftb_q.m_size) {
8432 m_ftb_q.pop_entry(&p1,&p2,&ident);
8433 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8434 pending_bd_q.insert_entry(p1,p2,ident);
8435 } else {
8436 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008437 }
Arun Menon906de572013-06-18 17:01:40 -07008438 }
8439 //return all non GENERATE FDB to ftb queue
8440 while (tmp_q.m_size) {
8441 tmp_q.pop_entry(&p1,&p2,&ident);
8442 m_ftb_q.insert_entry(p1,p2,ident);
8443 }
8444 // pop all pending GENERATE EDB from etb queue
8445 while (m_etb_q.m_size) {
8446 m_etb_q.pop_entry(&p1,&p2,&ident);
8447 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8448 pending_bd_q.insert_entry(p1,p2,ident);
8449 } else {
8450 tmp_q.insert_entry(p1,p2,ident);
8451 }
8452 }
8453 //return all non GENERATE FDB to etb queue
8454 while (tmp_q.m_size) {
8455 tmp_q.pop_entry(&p1,&p2,&ident);
8456 m_etb_q.insert_entry(p1,p2,ident);
8457 }
8458 pthread_mutex_unlock(&m_lock);
8459 // process all pending buffer dones
8460 while (pending_bd_q.m_size) {
8461 pending_bd_q.pop_entry(&p1,&p2,&ident);
8462 switch (ident) {
8463 case OMX_COMPONENT_GENERATE_EBD:
8464 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008465 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008466 omx_report_error ();
8467 }
8468 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008469
Arun Menon906de572013-06-18 17:01:40 -07008470 case OMX_COMPONENT_GENERATE_FBD:
8471 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008472 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008473 omx_report_error ();
8474 }
8475 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008476 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008477 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008478}
8479
8480void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8481{
Arun Menon906de572013-06-18 17:01:40 -07008482 OMX_U32 new_frame_interval = 0;
8483 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8484 && llabs(act_timestamp - prev_ts) > 2000) {
8485 new_frame_interval = client_set_fps ? frm_int :
8486 llabs(act_timestamp - prev_ts);
Arun Menond9e49f82014-04-23 18:50:26 -07008487 if (new_frame_interval != frm_int || frm_int == 0) {
Arun Menon906de572013-06-18 17:01:40 -07008488 frm_int = new_frame_interval;
8489 if (frm_int) {
8490 drv_ctx.frame_rate.fps_numerator = 1e6;
8491 drv_ctx.frame_rate.fps_denominator = frm_int;
8492 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8493 frm_int, drv_ctx.frame_rate.fps_numerator /
8494 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008495
Arun Menon906de572013-06-18 17:01:40 -07008496 /* We need to report the difference between this FBD and the previous FBD
8497 * back to the driver for clock scaling purposes. */
8498 struct v4l2_outputparm oparm;
8499 /*XXX: we're providing timing info as seconds per frame rather than frames
8500 * per second.*/
8501 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8502 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008503
Arun Menon906de572013-06-18 17:01:40 -07008504 struct v4l2_streamparm sparm;
8505 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8506 sparm.parm.output = oparm;
8507 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8508 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8509 performance might be affected");
8510 }
8511
8512 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008513 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008514 }
Arun Menon906de572013-06-18 17:01:40 -07008515 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008516}
8517
8518void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8519{
Arun Menon906de572013-06-18 17:01:40 -07008520 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8521 prev_ts = act_timestamp;
8522 rst_prev_ts = false;
8523 } else if (VALID_TS(prev_ts)) {
8524 bool codec_cond = (drv_ctx.timestamp_adjust)?
Deva Ramasubramanian5f3cff32014-12-04 17:13:01 -08008525 (!VALID_TS(act_timestamp) || act_timestamp < prev_ts || llabs(act_timestamp - prev_ts) <= 2000) :
8526 (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts);
Arun Menon906de572013-06-18 17:01:40 -07008527 if (frm_int > 0 && codec_cond) {
8528 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8529 act_timestamp = prev_ts + frm_int;
8530 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8531 prev_ts = act_timestamp;
Leena Winterrowdd139fdc2014-08-05 18:04:25 -07008532 } else {
8533 if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
8534 // ensure that timestamps can never step backwards when in display order
8535 act_timestamp = prev_ts;
8536 }
Arun Menon906de572013-06-18 17:01:40 -07008537 set_frame_rate(act_timestamp);
Leena Winterrowdd139fdc2014-08-05 18:04:25 -07008538 }
Arun Menon906de572013-06-18 17:01:40 -07008539 } else if (frm_int > 0) // In this case the frame rate was set along
8540 { // with the port definition, start ts with 0
8541 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8542 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008543 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008544}
8545
8546void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8547{
Arun Menon906de572013-06-18 17:01:40 -07008548 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8549 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308550 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008551 OMX_U32 frame_rate = 0;
8552 int consumed_len = 0;
8553 OMX_U32 num_MB_in_frame;
8554 OMX_U32 recovery_sei_flags = 1;
8555 int enable = 0;
Arun Menon7b6fd642014-02-13 16:48:36 -08008556
Arun Menon906de572013-06-18 17:01:40 -07008557 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008558 if (buf_index >= drv_ctx.extradata_info.count) {
8559 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8560 buf_index, drv_ctx.extradata_info.count);
8561 return;
8562 }
Arun Menon906de572013-06-18 17:01:40 -07008563 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8564 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8565 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308566
Arun Menon906de572013-06-18 17:01:40 -07008567 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308568 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008569 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008570 }
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308571
8572 if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
8573 DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
8574 p_extra = NULL;
8575 return;
8576 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308577 if (!secure_mode)
8578 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008579 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308580 else
8581 p_extra = m_other_extradata;
8582
Arun Menon906de572013-06-18 17:01:40 -07008583 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308584 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
8585 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
Arun Menon906de572013-06-18 17:01:40 -07008586 p_extra = NULL;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308587 return;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008588 }
Arun Menon906de572013-06-18 17:01:40 -07008589 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008590 if (data && p_extra) {
Arun Menon906de572013-06-18 17:01:40 -07008591 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8592 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308593 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008594 DEBUG_PRINT_LOW("Invalid extra data size");
8595 break;
8596 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308597 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008598 switch ((unsigned long)data->eType) {
8599 case EXTRADATA_INTERLACE_VIDEO:
8600 struct msm_vidc_interlace_payload *payload;
8601 payload = (struct msm_vidc_interlace_payload *)data->data;
Arun Menon7b6fd642014-02-13 16:48:36 -08008602 if (payload) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008603 enable = 1;
Arun Menon7b6fd642014-02-13 16:48:36 -08008604 switch (payload->format) {
8605 case INTERLACE_FRAME_PROGRESSIVE:
8606 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8607 enable = 0;
8608 break;
8609 case INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
8610 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8611 break;
8612 case INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
8613 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
8614 break;
8615 default:
8616 DEBUG_PRINT_LOW("default case - set interlace to topfield");
8617 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8618 }
Arun Menon906de572013-06-18 17:01:40 -07008619 }
8620 if (m_enable_android_native_buffers)
8621 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8622 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308623 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon7b6fd642014-02-13 16:48:36 -08008624 append_interlace_extradata(p_extra, payload->format,
8625 p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
Arun Menon906de572013-06-18 17:01:40 -07008626 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8627 }
8628 break;
8629 case EXTRADATA_FRAME_RATE:
8630 struct msm_vidc_framerate_payload *frame_rate_payload;
8631 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8632 frame_rate = frame_rate_payload->frame_rate;
8633 break;
8634 case EXTRADATA_TIMESTAMP:
8635 struct msm_vidc_ts_payload *time_stamp_payload;
8636 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308637 time_stamp = time_stamp_payload->timestamp_lo;
8638 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8639 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008640 break;
8641 case EXTRADATA_NUM_CONCEALED_MB:
8642 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8643 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8644 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8645 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8646 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8647 break;
8648 case EXTRADATA_INDEX:
8649 int *etype;
8650 etype = (int *)(data->data);
8651 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8652 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8653 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8654 if (aspect_ratio_payload) {
8655 ((struct vdec_output_frameinfo *)
8656 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8657 ((struct vdec_output_frameinfo *)
8658 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8659 }
8660 }
8661 break;
8662 case EXTRADATA_RECOVERY_POINT_SEI:
8663 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8664 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8665 recovery_sei_flags = recovery_sei_payload->flags;
8666 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8667 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008668 DEBUG_PRINT_HIGH("");
8669 DEBUG_PRINT_HIGH("***************************************************");
8670 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8671 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008672 }
8673 break;
8674 case EXTRADATA_PANSCAN_WINDOW:
8675 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8676 break;
8677 case EXTRADATA_MPEG2_SEQDISP:
8678 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8679 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8680 if (seqdisp_payload) {
8681 m_disp_hor_size = seqdisp_payload->disp_width;
8682 m_disp_vert_size = seqdisp_payload->disp_height;
8683 }
8684 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308685 case EXTRADATA_S3D_FRAME_PACKING:
8686 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8687 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308688 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308689 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8690 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8691 }
8692 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008693 case EXTRADATA_FRAME_QP:
8694 struct msm_vidc_frame_qp_payload *qp_payload;
8695 qp_payload = (struct msm_vidc_frame_qp_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308696 if (client_extradata & OMX_QP_EXTRADATA) {
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008697 append_qp_extradata(p_extra, qp_payload);
8698 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8699 }
8700 break;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008701 case EXTRADATA_FRAME_BITS_INFO:
8702 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
8703 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308704 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008705 append_bitsinfo_extradata(p_extra, bits_info_payload);
8706 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8707 }
8708 break;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008709 case EXTRADATA_STREAM_USERDATA:
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308710 if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008711 append_user_extradata(p_extra, data);
8712 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8713 }
8714 break;
Arun Menon906de572013-06-18 17:01:40 -07008715 default:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008716 DEBUG_PRINT_LOW("Unrecognized extradata");
Arun Menon906de572013-06-18 17:01:40 -07008717 goto unrecognized_extradata;
8718 }
8719 consumed_len += data->nSize;
8720 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8721 }
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308722 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008723 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8724 append_frame_info_extradata(p_extra,
8725 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308726 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008727 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008728 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008729 }
8730 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008731unrecognized_extradata:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008732 if (client_extradata && p_extra) {
8733 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Arun Menon906de572013-06-18 17:01:40 -07008734 append_terminator_extradata(p_extra);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008735 }
8736
Arun Menonfd723932014-05-30 17:56:31 -07008737 if (secure_mode && p_extradata && m_other_extradata) {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308738 struct vdec_output_frameinfo *ptr_extradatabuff = NULL;
8739 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
8740 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
8741 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
8742 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
8743 }
Arun Menon906de572013-06-18 17:01:40 -07008744 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008745}
8746
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008747OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008748 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008749{
Arun Menon906de572013-06-18 17:01:40 -07008750 OMX_ERRORTYPE ret = OMX_ErrorNone;
8751 struct v4l2_control control;
8752 if (m_state != OMX_StateLoaded) {
8753 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8754 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008755 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008756 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008757 client_extradata, requested_extradata, enable, is_internal);
8758
8759 if (!is_internal) {
8760 if (enable)
8761 client_extradata |= requested_extradata;
8762 else
8763 client_extradata = client_extradata & ~requested_extradata;
8764 }
8765
8766 if (enable) {
8767 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8768 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8769 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8770 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8771 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008772 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008773 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308774 }
8775 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008776 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8777 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8778 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008779 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008780 }
8781 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8782 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8783 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008784 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008785 }
8786 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8787 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
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 recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008790 }
8791 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8792 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8793 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008794 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008795 }
8796 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8797 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8798 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008799 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008800 }
8801 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8802 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8803 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8804 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008805 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008806 }
8807 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308808 }
8809 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008810 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8811 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8812 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008813 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008814 }
8815 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308816 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8817 if (output_capability == V4L2_PIX_FMT_H264) {
8818 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8819 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8820 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8821 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8822 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8823 }
8824 } else {
8825 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8826 }
8827 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008828 if (requested_extradata & OMX_QP_EXTRADATA) {
8829 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8830 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
8831 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8832 DEBUG_PRINT_HIGH("Failed to set QP extradata");
8833 }
8834 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008835 if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
8836 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8837 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
8838 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8839 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
8840 }
8841 }
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008842 if (requested_extradata & OMX_EXTNUSER_EXTRADATA) {
8843 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8844 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
8845 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8846 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
8847 }
8848 }
Arun Menon906de572013-06-18 17:01:40 -07008849 }
8850 ret = get_buffer_req(&drv_ctx.op_buf);
8851 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008852}
8853
8854OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8855{
Arun Menon906de572013-06-18 17:01:40 -07008856 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8857 OMX_U8 *data_ptr = extra->data, data = 0;
8858 while (byte_count < extra->nDataSize) {
8859 data = *data_ptr;
8860 while (data) {
8861 num_MB += (data&0x01);
8862 data >>= 1;
8863 }
8864 data_ptr++;
8865 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008866 }
Arun Menon906de572013-06-18 17:01:40 -07008867 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8868 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8869 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008870}
8871
8872void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8873{
Arun Menon906de572013-06-18 17:01:40 -07008874 if (!m_debug_extradata)
8875 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008876
8877 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308878 "============== Extra Data ==============\n"
8879 " Size: %lu\n"
8880 " Version: %lu\n"
8881 " PortIndex: %lu\n"
8882 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008883 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008884 extra->nSize, extra->nVersion.nVersion,
8885 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008886
Arun Menon906de572013-06-18 17:01:40 -07008887 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8888 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8889 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308890 "------ Interlace Format ------\n"
8891 " Size: %lu\n"
8892 " Version: %lu\n"
8893 " PortIndex: %lu\n"
8894 " Is Interlace Format: %d\n"
8895 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008896 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008897 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8898 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8899 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8900 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8901
8902 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308903 "-------- Frame Format --------\n"
8904 " Picture Type: %d\n"
8905 " Interlace Type: %d\n"
8906 " Pan Scan Total Frame Num: %lu\n"
8907 " Concealed Macro Blocks: %lu\n"
8908 " frame rate: %lu\n"
8909 " Time Stamp: %llu\n"
8910 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008911 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008912 fminfo->ePicType,
8913 fminfo->interlaceType,
8914 fminfo->panScan.numWindows,
8915 fminfo->nConcealedMacroblocks,
8916 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308917 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008918 fminfo->aspectRatio.aspectRatioX,
8919 fminfo->aspectRatio.aspectRatioY);
8920
8921 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8922 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008923 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308924 " Pan Scan Frame Num: %lu\n"
8925 " Rectangle x: %ld\n"
8926 " Rectangle y: %ld\n"
8927 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008928 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008929 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8930 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8931 }
8932
8933 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308934 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8935 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8936 DEBUG_PRINT_HIGH(
8937 "------------------ Framepack Format ----------\n"
8938 " id: %lu \n"
8939 " cancel_flag: %lu \n"
8940 " type: %lu \n"
8941 " quincunx_sampling_flagFormat: %lu \n"
8942 " content_interpretation_type: %lu \n"
8943 " content_interpretation_type: %lu \n"
8944 " spatial_flipping_flag: %lu \n"
8945 " frame0_flipped_flag: %lu \n"
8946 " field_views_flag: %lu \n"
8947 " current_frame_is_frame0_flag: %lu \n"
8948 " frame0_self_contained_flag: %lu \n"
8949 " frame1_self_contained_flag: %lu \n"
8950 " frame0_grid_position_x: %lu \n"
8951 " frame0_grid_position_y: %lu \n"
8952 " frame1_grid_position_x: %lu \n"
8953 " frame1_grid_position_y: %lu \n"
8954 " reserved_byte: %lu \n"
8955 " repetition_period: %lu \n"
8956 " extension_flag: %lu \n"
8957 "================== End of Framepack ===========",
8958 framepack->id,
8959 framepack->cancel_flag,
8960 framepack->type,
8961 framepack->quincunx_sampling_flag,
8962 framepack->content_interpretation_type,
8963 framepack->spatial_flipping_flag,
8964 framepack->frame0_flipped_flag,
8965 framepack->field_views_flag,
8966 framepack->current_frame_is_frame0_flag,
8967 framepack->frame0_self_contained_flag,
8968 framepack->frame1_self_contained_flag,
8969 framepack->frame0_grid_position_x,
8970 framepack->frame0_grid_position_y,
8971 framepack->frame1_grid_position_x,
8972 framepack->frame1_grid_position_y,
8973 framepack->reserved_byte,
8974 framepack->repetition_period,
8975 framepack->extension_flag);
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008976 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
8977 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8978 DEBUG_PRINT_HIGH(
8979 "---- QP (Frame quantization parameter) ----\n"
8980 " Frame QP: %lu \n"
8981 "================ End of QP ================\n",
8982 qp->nQP);
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008983 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
8984 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)extra->data;
8985 DEBUG_PRINT_HIGH(
8986 "--------- Input bits information --------\n"
8987 " Header bits: %lu \n"
8988 " Frame bits: %lu \n"
8989 "===== End of Input bits information =====\n",
8990 bits->header_bits, bits->frame_bits);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008991 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
8992 OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)extra->data;
8993 OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
8994 OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
8995 OMX_U32 i = 0;
8996 DEBUG_PRINT_HIGH(
8997 "-------------- Userdata -------------\n"
8998 " Stream userdata type: %d\n"
8999 " userdata size: %d\n"
9000 " STREAM_USERDATA:",
9001 userdata->type, userdata_size);
9002 for (i = 0; i < userdata_size; i+=4) {
9003 DEBUG_PRINT_HIGH(" %x %x %x %x",
9004 data_ptr[i], data_ptr[i+1],
9005 data_ptr[i+2], data_ptr[i+3]);
9006 }
9007 DEBUG_PRINT_HIGH(
9008 "=========== End of Userdata ===========");
Arun Menon906de572013-06-18 17:01:40 -07009009 } else if (extra->eType == OMX_ExtraDataNone) {
9010 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
9011 } else {
9012 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07009013 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009014}
9015
9016void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon7b6fd642014-02-13 16:48:36 -08009017 OMX_U32 interlaced_format_type, bool is_mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009018{
Arun Menon906de572013-06-18 17:01:40 -07009019 OMX_STREAMINTERLACEFORMAT *interlace_format;
Arun Menon7b6fd642014-02-13 16:48:36 -08009020
Arun Menon906de572013-06-18 17:01:40 -07009021 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
9022 return;
9023 }
9024 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
9025 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9026 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9027 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
9028 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9029 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
9030 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9031 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
9032 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
Arun Menon7b6fd642014-02-13 16:48:36 -08009033
9034 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
Arun Menon906de572013-06-18 17:01:40 -07009035 interlace_format->bInterlaceFormat = OMX_FALSE;
9036 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
9037 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08009038 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009039 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08009040 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009041 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08009042 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009043 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08009044 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009045 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07009046 } else {
9047 interlace_format->bInterlaceFormat = OMX_TRUE;
9048 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
9049 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
9050 }
9051 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009052}
9053
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009054void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07009055 struct vdec_aspectratioinfo *aspect_ratio_info,
9056 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009057{
Arun Menon906de572013-06-18 17:01:40 -07009058 m_extradata = frame_info;
9059 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
9060 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309061 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07009062 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009063}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009064
9065void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07009066 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309067 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009068 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009069{
Arun Menon906de572013-06-18 17:01:40 -07009070 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
9071 struct msm_vidc_panscan_window *panscan_window;
9072 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009073 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009074 }
Arun Menon906de572013-06-18 17:01:40 -07009075 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
9076 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9077 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9078 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
9079 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
9080 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
9081 switch (picture_type) {
9082 case PICTURE_TYPE_I:
9083 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
9084 break;
9085 case PICTURE_TYPE_P:
9086 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
9087 break;
9088 case PICTURE_TYPE_B:
9089 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
9090 break;
9091 default:
9092 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
9093 }
9094 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
9095 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
9096 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
9097 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
9098 else
9099 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
9100 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
9101 frame_info->nConcealedMacroblocks = num_conceal_mb;
9102 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309103 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07009104 frame_info->panScan.numWindows = 0;
9105 if (output_capability == V4L2_PIX_FMT_MPEG2) {
9106 if (m_disp_hor_size && m_disp_vert_size) {
9107 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
9108 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
Pushkaraj Patil5e6ebd92014-03-10 10:29:14 +05309109 } else {
9110 frame_info->displayAspectRatio.displayHorizontalSize = 0;
9111 frame_info->displayAspectRatio.displayVerticalSize = 0;
Arun Menon906de572013-06-18 17:01:40 -07009112 }
9113 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009114
Arun Menon906de572013-06-18 17:01:40 -07009115 if (panscan_payload) {
9116 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
9117 panscan_window = &panscan_payload->wnd[0];
9118 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
9119 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
9120 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
9121 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
9122 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
9123 panscan_window++;
9124 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009125 }
Arun Menon906de572013-06-18 17:01:40 -07009126 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
9127 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009128}
9129
9130void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9131{
Arun Menon906de572013-06-18 17:01:40 -07009132 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
9133 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
9134 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9135 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9136 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
9137 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
9138 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
9139 *portDefn = m_port_def;
9140 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009141 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07009142 portDefn->format.video.nFrameWidth,
9143 portDefn->format.video.nStride,
9144 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009145}
9146
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05309147void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9148 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
9149{
9150 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
9151 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
9152 DEBUG_PRINT_ERROR("frame packing size mismatch");
9153 return;
9154 }
9155 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
9156 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9157 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9158 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
9159 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9160 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
9161 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9162 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
9163 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9164 memcpy(&framepack->id, s3d_frame_packing_payload,
9165 sizeof(struct msm_vidc_s3d_frame_packing_payload));
9166 memcpy(&m_frame_pack_arrangement, framepack,
9167 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
9168 print_debug_extradata(extra);
9169}
9170
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08009171void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9172 struct msm_vidc_frame_qp_payload *qp_payload)
9173{
9174 OMX_QCOM_EXTRADATA_QP * qp = NULL;
9175 if (!qp_payload) {
9176 DEBUG_PRINT_ERROR("QP payload is NULL");
9177 return;
9178 }
9179 extra->nSize = OMX_QP_EXTRADATA_SIZE;
9180 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9181 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9182 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
9183 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
9184 qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
9185 qp->nQP = qp_payload->frame_qp;
9186 print_debug_extradata(extra);
9187}
9188
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08009189void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9190 struct msm_vidc_frame_bits_info_payload *bits_payload)
9191{
9192 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
9193 if (!bits_payload) {
9194 DEBUG_PRINT_ERROR("bits info payload is NULL");
9195 return;
9196 }
9197 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
9198 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9199 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9200 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
9201 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
9202 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)extra->data;
9203 bits->frame_bits = bits_payload->frame_bits;
9204 bits->header_bits = bits_payload->header_bits;
9205 print_debug_extradata(extra);
9206}
9207
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009208void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9209 OMX_OTHER_EXTRADATATYPE *p_user)
9210{
9211 int userdata_size = 0;
9212 struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
9213 userdata_payload =
9214 (struct msm_vidc_stream_userdata_payload *)p_user->data;
9215 userdata_size = p_user->nDataSize;
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07009216 extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + p_user->nSize;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009217 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9218 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9219 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
9220 extra->nDataSize = userdata_size;
9221 if (extra->data && p_user->data && extra->nDataSize)
9222 memcpy(extra->data, p_user->data, extra->nDataSize);
9223 print_debug_extradata(extra);
9224}
9225
Shalaj Jain273b3e02012-06-22 19:08:03 -07009226void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9227{
Arun Menon906de572013-06-18 17:01:40 -07009228 if (!client_extradata) {
9229 return;
9230 }
9231 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
9232 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9233 extra->eType = OMX_ExtraDataNone;
9234 extra->nDataSize = 0;
9235 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009236
Arun Menon906de572013-06-18 17:01:40 -07009237 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009238}
9239
9240OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
9241{
Arun Menon906de572013-06-18 17:01:40 -07009242 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9243 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009244 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07009245 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009246 }
Arun Menon906de572013-06-18 17:01:40 -07009247 if (m_desc_buffer_ptr == NULL) {
9248 m_desc_buffer_ptr = (desc_buffer_hdr*) \
9249 calloc( (sizeof(desc_buffer_hdr)),
9250 drv_ctx.ip_buf.actualcount);
9251 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009252 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009253 return OMX_ErrorInsufficientResources;
9254 }
9255 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009256
Arun Menon906de572013-06-18 17:01:40 -07009257 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
9258 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009259 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009260 return OMX_ErrorInsufficientResources;
9261 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009262
Arun Menon906de572013-06-18 17:01:40 -07009263 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009264}
9265
9266void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
9267{
Arun Menon906de572013-06-18 17:01:40 -07009268 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
9269 if (m_demux_entries < 8192) {
9270 m_demux_offsets[m_demux_entries++] = address_offset;
9271 }
9272 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009273}
9274
9275void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
9276{
Arun Menon906de572013-06-18 17:01:40 -07009277 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
9278 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
9279 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009280
Arun Menon906de572013-06-18 17:01:40 -07009281 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009282
Arun Menon906de572013-06-18 17:01:40 -07009283 while (index < bytes_to_parse) {
9284 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9285 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
9286 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9287 (buf[index+2] == 0x01)) ) {
9288 //Found start code, insert address offset
9289 insert_demux_addr_offset(index);
9290 if (buf[index+2] == 0x01) // 3 byte start code
9291 index += 3;
9292 else //4 byte start code
9293 index += 4;
9294 } else
9295 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009296 }
Arun Menon906de572013-06-18 17:01:40 -07009297 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
9298 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009299}
9300
9301OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
9302{
Arun Menon906de572013-06-18 17:01:40 -07009303 //fix this, handle 3 byte start code, vc1 terminator entry
9304 OMX_U8 *p_demux_data = NULL;
9305 OMX_U32 desc_data = 0;
9306 OMX_U32 start_addr = 0;
9307 OMX_U32 nal_size = 0;
9308 OMX_U32 suffix_byte = 0;
9309 OMX_U32 demux_index = 0;
9310 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009311
Arun Menon906de572013-06-18 17:01:40 -07009312 if (m_desc_buffer_ptr == NULL) {
9313 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
9314 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009315 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009316
Arun Menon906de572013-06-18 17:01:40 -07009317 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
9318 if (buffer_index > drv_ctx.ip_buf.actualcount) {
9319 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
9320 return OMX_ErrorBadParameter;
9321 }
9322
9323 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9324
9325 if ( ((OMX_U8*)p_demux_data == NULL) ||
9326 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
9327 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9328 return OMX_ErrorBadParameter;
9329 } else {
9330 for (; demux_index < m_demux_entries; demux_index++) {
9331 desc_data = 0;
9332 start_addr = m_demux_offsets[demux_index];
9333 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
9334 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9335 } else {
9336 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9337 }
9338 if (demux_index < (m_demux_entries - 1)) {
9339 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9340 } else {
9341 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9342 }
9343 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9344 (void *)start_addr,
9345 suffix_byte,
9346 nal_size,
9347 demux_index);
9348 desc_data = (start_addr >> 3) << 1;
9349 desc_data |= (start_addr & 7) << 21;
9350 desc_data |= suffix_byte << 24;
9351
9352 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9353 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9354 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9355 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9356
9357 p_demux_data += 16;
9358 }
9359 if (codec_type_parse == CODEC_TYPE_VC1) {
9360 DEBUG_PRINT_LOW("VC1 terminator entry");
9361 desc_data = 0;
9362 desc_data = 0x82 << 24;
9363 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9364 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9365 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9366 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9367 p_demux_data += 16;
9368 m_demux_entries++;
9369 }
9370 //Add zero word to indicate end of descriptors
9371 memset(p_demux_data, 0, sizeof(OMX_U32));
9372
9373 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
9374 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
9375 }
9376 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9377 m_demux_entries = 0;
9378 DEBUG_PRINT_LOW("Demux table complete!");
9379 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009380}
9381
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009382OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009383{
Arun Menon906de572013-06-18 17:01:40 -07009384 OMX_ERRORTYPE err = OMX_ErrorNone;
9385 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9386 if (iDivXDrmDecrypt) {
9387 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9388 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009389 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009390 delete iDivXDrmDecrypt;
9391 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07009392 }
9393 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009394 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07009395 err = OMX_ErrorUndefined;
9396 }
9397 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009398}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009399
Vinay Kaliada4f4422013-01-09 10:45:03 -08009400omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9401{
Arun Menon906de572013-06-18 17:01:40 -07009402 enabled = false;
9403 omx = NULL;
9404 init_members();
9405 ColorFormat = OMX_COLOR_FormatMax;
Praveen Chavandb7776f2014-02-06 18:17:25 -08009406 dest_format = YCbCr420P;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009407}
9408
9409void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9410{
Arun Menon906de572013-06-18 17:01:40 -07009411 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009412}
9413
Arun Menon906de572013-06-18 17:01:40 -07009414void omx_vdec::allocate_color_convert_buf::init_members()
9415{
9416 allocated_count = 0;
9417 buffer_size_req = 0;
9418 buffer_alignment_req = 0;
9419 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9420 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9421 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9422 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009423#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009424 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009425#endif
Arun Menon906de572013-06-18 17:01:40 -07009426 for (int i = 0; i < MAX_COUNT; i++)
9427 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009428}
9429
Arun Menon906de572013-06-18 17:01:40 -07009430omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9431{
9432 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08009433}
9434
9435bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9436{
Arun Menon906de572013-06-18 17:01:40 -07009437 bool status = true;
9438 unsigned int src_size = 0, destination_size = 0;
9439 OMX_COLOR_FORMATTYPE drv_color_format;
9440 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009441 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009442 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009443 }
Arun Menon906de572013-06-18 17:01:40 -07009444 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009445 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07009446 return status;
9447 }
9448 pthread_mutex_lock(&omx->c_lock);
9449 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9450 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009451 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07009452 status = false;
9453 goto fail_update_buf_req;
9454 }
9455 c2d.close();
9456 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9457 omx->drv_ctx.video_resolution.frame_width,
Praveen Chavandb7776f2014-02-06 18:17:25 -08009458 NV12_128m,dest_format);
Arun Menon906de572013-06-18 17:01:40 -07009459 if (status) {
9460 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9461 if (status)
9462 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9463 }
9464 if (status) {
9465 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9466 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009467 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07009468 "driver size %d destination size %d",
9469 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9470 status = false;
9471 c2d.close();
9472 buffer_size_req = 0;
9473 } else {
9474 buffer_size_req = destination_size;
9475 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9476 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9477 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9478 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9479 }
9480 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009481fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07009482 pthread_mutex_unlock(&omx->c_lock);
9483 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009484}
9485
9486bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07009487 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009488{
Arun Menon906de572013-06-18 17:01:40 -07009489 bool status = true;
9490 OMX_COLOR_FORMATTYPE drv_color_format;
9491 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009492 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009493 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009494 }
Arun Menon906de572013-06-18 17:01:40 -07009495 pthread_mutex_lock(&omx->c_lock);
9496 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9497 drv_color_format = (OMX_COLOR_FORMATTYPE)
9498 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9499 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009500 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07009501 status = false;
9502 }
9503 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009504 DEBUG_PRINT_LOW("Enabling C2D");
Praveen Chavandb7776f2014-02-06 18:17:25 -08009505 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
9506 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009507 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009508 status = false;
9509 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009510 ColorFormat = dest_color_format;
9511 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
9512 YCbCr420P : YCbCr420SP;
Arun Menon906de572013-06-18 17:01:40 -07009513 if (enabled)
9514 c2d.destroy();
9515 enabled = false;
9516 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009517 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009518 status = false;
9519 } else
9520 enabled = true;
9521 }
9522 } else {
9523 if (enabled)
9524 c2d.destroy();
9525 enabled = false;
9526 }
9527 pthread_mutex_unlock(&omx->c_lock);
9528 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009529}
9530
9531OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9532{
Arun Menon906de572013-06-18 17:01:40 -07009533 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009534 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009535 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009536 }
Arun Menon906de572013-06-18 17:01:40 -07009537 if (!enabled)
9538 return omx->m_out_mem_ptr;
9539 return m_out_mem_ptr_client;
9540}
9541
9542 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9543(OMX_BUFFERHEADERTYPE *bufadd)
9544{
9545 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009546 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009547 return NULL;
9548 }
9549 if (!enabled)
9550 return bufadd;
9551
9552 unsigned index = 0;
9553 index = bufadd - omx->m_out_mem_ptr;
9554 if (index < omx->drv_ctx.op_buf.actualcount) {
9555 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9556 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9557 bool status;
9558 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9559 pthread_mutex_lock(&omx->c_lock);
9560 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9561 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9562 pmem_baseaddress[index], pmem_baseaddress[index]);
Arun Menon906de572013-06-18 17:01:40 -07009563 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009564 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009565 m_out_mem_ptr_client[index].nFilledLen = 0;
Leena Winterrowd270a7042014-09-30 13:05:55 -07009566 pthread_mutex_unlock(&omx->c_lock);
Arun Menon906de572013-06-18 17:01:40 -07009567 return &m_out_mem_ptr_client[index];
Praveen Chavan6d6b7252014-09-15 17:05:54 -07009568 } else {
9569 unsigned int filledLen = 0;
9570 c2d.get_output_filled_length(filledLen);
9571 m_out_mem_ptr_client[index].nFilledLen = filledLen;
Arun Menon906de572013-06-18 17:01:40 -07009572 }
Leena Winterrowd270a7042014-09-30 13:05:55 -07009573 pthread_mutex_unlock(&omx->c_lock);
Arun Menon906de572013-06-18 17:01:40 -07009574 } else
9575 m_out_mem_ptr_client[index].nFilledLen = 0;
9576 return &m_out_mem_ptr_client[index];
9577 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009578 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009579 return NULL;
9580}
9581
9582 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9583(OMX_BUFFERHEADERTYPE *bufadd)
9584{
9585 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009586 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009587 return NULL;
9588 }
9589 if (!enabled)
9590 return bufadd;
9591 unsigned index = 0;
9592 index = bufadd - m_out_mem_ptr_client;
9593 if (index < omx->drv_ctx.op_buf.actualcount) {
9594 return &omx->m_out_mem_ptr[index];
9595 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009596 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009597 return NULL;
9598}
9599 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9600(unsigned int &buffer_size)
9601{
9602 bool status = true;
9603 pthread_mutex_lock(&omx->c_lock);
9604 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009605 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009606 else {
9607 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009608 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009609 status = false;
9610 goto fail_get_buffer_size;
9611 }
9612 }
9613 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9614 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9615 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9616 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009617fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009618 pthread_mutex_unlock(&omx->c_lock);
9619 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009620}
9621OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009622 OMX_BUFFERHEADERTYPE *bufhdr)
9623{
9624 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009625
Arun Menon906de572013-06-18 17:01:40 -07009626 if (!enabled)
9627 return omx->free_output_buffer(bufhdr);
9628 if (enabled && omx->is_component_secure())
9629 return OMX_ErrorNone;
9630 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009631 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009632 return OMX_ErrorBadParameter;
9633 }
9634 index = bufhdr - m_out_mem_ptr_client;
9635 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009636 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009637 return OMX_ErrorBadParameter;
9638 }
9639 if (pmem_fd[index] > 0) {
9640 munmap(pmem_baseaddress[index], buffer_size_req);
9641 close(pmem_fd[index]);
9642 }
9643 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009644#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009645 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009646#endif
Arun Menon906de572013-06-18 17:01:40 -07009647 m_heap_ptr[index].video_heap_ptr = NULL;
9648 if (allocated_count > 0)
9649 allocated_count--;
9650 else
9651 allocated_count = 0;
9652 if (!allocated_count) {
9653 pthread_mutex_lock(&omx->c_lock);
9654 c2d.close();
9655 init_members();
9656 pthread_mutex_unlock(&omx->c_lock);
9657 }
9658 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009659}
9660
9661OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009662 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009663{
Arun Menon906de572013-06-18 17:01:40 -07009664 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9665 if (!enabled) {
9666 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9667 return eRet;
9668 }
9669 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009670 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009671 omx->is_component_secure());
9672 return OMX_ErrorUnsupportedSetting;
9673 }
9674 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009675 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9676 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009677 buffer_size_req,bytes);
9678 return OMX_ErrorBadParameter;
9679 }
9680 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009681 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009682 return OMX_ErrorInsufficientResources;
9683 }
9684 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9685 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9686 port,appData,omx->drv_ctx.op_buf.buffer_size);
9687 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009688 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009689 return eRet;
9690 }
9691 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309692 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009693 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009694 (temp_bufferHdr - omx->m_out_mem_ptr));
9695 return OMX_ErrorUndefined;
9696 }
9697 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009698#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009699 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9700 buffer_size_req,buffer_alignment_req,
9701 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9702 0);
9703 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9704 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009705 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009706 return OMX_ErrorInsufficientResources;
9707 }
9708 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9709 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009710
Arun Menon906de572013-06-18 17:01:40 -07009711 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009712 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009713 close(pmem_fd[i]);
9714 omx->free_ion_memory(&op_buf_ion_info[i]);
9715 return OMX_ErrorInsufficientResources;
9716 }
9717 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9718 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9719 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009720#endif
Arun Menon906de572013-06-18 17:01:40 -07009721 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9722 m_pmem_info_client[i].offset = 0;
9723 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9724 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9725 m_platform_list_client[i].nEntries = 1;
9726 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9727 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9728 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9729 m_out_mem_ptr_client[i].nFilledLen = 0;
9730 m_out_mem_ptr_client[i].nFlags = 0;
9731 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9732 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9733 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9734 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9735 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9736 m_out_mem_ptr_client[i].pAppPrivate = appData;
9737 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009738 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009739 allocated_count++;
9740 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009741}
9742
9743bool omx_vdec::is_component_secure()
9744{
Arun Menon906de572013-06-18 17:01:40 -07009745 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009746}
9747
9748bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9749{
Arun Menon906de572013-06-18 17:01:40 -07009750 bool status = true;
9751 if (!enabled) {
9752 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9753 dest_color_format = (OMX_COLOR_FORMATTYPE)
9754 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9755 else
9756 status = false;
9757 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009758 if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
9759 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
9760 dest_color_format = ColorFormat;
Arun Menon906de572013-06-18 17:01:40 -07009761 } else
Praveen Chavandb7776f2014-02-06 18:17:25 -08009762 status = false;
Arun Menon906de572013-06-18 17:01:40 -07009763 }
9764 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009765}
Arun Menonbdb80b02013-08-12 17:45:54 -07009766
Arun Menonbdb80b02013-08-12 17:45:54 -07009767void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9768{
9769 int i = 0;
9770 bool buf_present = false;
9771 pthread_mutex_lock(&m_lock);
9772 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9773 //check the buffer fd, offset, uv addr with list contents
9774 //If present increment reference.
9775 if ((out_dynamic_list[i].fd == fd) &&
9776 (out_dynamic_list[i].offset == offset)) {
9777 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009778 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009779 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9780 buf_present = true;
9781 break;
9782 }
9783 }
9784 if (!buf_present) {
9785 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9786 //search for a entry to insert details of the new buffer
9787 if (out_dynamic_list[i].dup_fd == 0) {
9788 out_dynamic_list[i].fd = fd;
9789 out_dynamic_list[i].offset = offset;
9790 out_dynamic_list[i].dup_fd = dup(fd);
9791 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009792 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009793 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9794 break;
9795 }
9796 }
9797 }
9798 pthread_mutex_unlock(&m_lock);
9799}
9800
9801void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9802{
9803 int i = 0;
9804 pthread_mutex_lock(&m_lock);
9805 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9806 //check the buffer fd, offset, uv addr with list contents
9807 //If present decrement reference.
9808 if ((out_dynamic_list[i].fd == fd) &&
9809 (out_dynamic_list[i].offset == offset)) {
9810 out_dynamic_list[i].ref_count--;
9811 if (out_dynamic_list[i].ref_count == 0) {
9812 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009813 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009814 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9815 out_dynamic_list[i].dup_fd = 0;
9816 out_dynamic_list[i].fd = 0;
9817 out_dynamic_list[i].offset = 0;
9818 }
9819 break;
9820 }
9821 }
9822 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009823 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009824 }
9825 pthread_mutex_unlock(&m_lock);
9826}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009827
Arun Menon1fc764f2014-04-17 15:41:27 -07009828OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
9829 unsigned long nMaxFrameHeight)
9830{
9831
9832 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9833 int ret = 0;
9834 unsigned long min_res_buf_count = 0;
9835
9836 eRet = enable_smoothstreaming();
9837 if (eRet != OMX_ErrorNone) {
9838 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
9839 return eRet;
9840 }
9841
9842 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
9843 nMaxFrameWidth,
9844 nMaxFrameHeight);
9845 m_smoothstreaming_mode = true;
9846 m_smoothstreaming_width = nMaxFrameWidth;
9847 m_smoothstreaming_height = nMaxFrameHeight;
9848
9849 //Get upper limit buffer count for min supported resolution
9850 struct v4l2_format fmt;
9851 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9852 fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
9853 fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
9854 fmt.fmt.pix_mp.pixelformat = output_capability;
9855
9856 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9857 if (ret) {
9858 DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
9859 m_decoder_capability.min_height,
9860 m_decoder_capability.min_width);
9861 return OMX_ErrorUnsupportedSetting;
9862 }
9863
9864 eRet = get_buffer_req(&drv_ctx.op_buf);
9865 if (eRet != OMX_ErrorNone) {
9866 DEBUG_PRINT_ERROR("failed to get_buffer_req");
9867 return eRet;
9868 }
9869
9870 min_res_buf_count = drv_ctx.op_buf.mincount;
9871 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
9872 min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
9873
9874 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
9875 m_smoothstreaming_width, m_smoothstreaming_height);
9876 eRet = is_video_session_supported();
9877 if (eRet != OMX_ErrorNone) {
9878 DEBUG_PRINT_ERROR("video session is not supported");
9879 return eRet;
9880 }
9881
9882 //Get upper limit buffer size for max smooth streaming resolution set
9883 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9884 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
9885 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
9886 fmt.fmt.pix_mp.pixelformat = output_capability;
9887 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9888 if (ret) {
9889 DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
9890 return OMX_ErrorUnsupportedSetting;
9891 }
9892
9893 eRet = get_buffer_req(&drv_ctx.op_buf);
9894 if (eRet != OMX_ErrorNone) {
9895 DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
9896 return eRet;
9897 }
9898 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
9899 drv_ctx.op_buf.buffer_size);
9900
9901 drv_ctx.op_buf.mincount = min_res_buf_count;
9902 drv_ctx.op_buf.actualcount = min_res_buf_count;
9903 eRet = set_buffer_req(&drv_ctx.op_buf);
9904 if (eRet != OMX_ErrorNone) {
9905 DEBUG_PRINT_ERROR("failed to set_buffer_req");
9906 return eRet;
9907 }
9908
9909 eRet = get_buffer_req(&drv_ctx.op_buf);
9910 if (eRet != OMX_ErrorNone) {
9911 DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
9912 return eRet;
9913 }
9914 DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
9915 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size);
9916 return eRet;
9917}
9918
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009919#ifdef _MSM8974_
9920void omx_vdec::send_codec_config() {
9921 if (codec_config_flag) {
9922 unsigned p1 = 0; // Parameter - 1
9923 unsigned p2 = 0; // Parameter - 2
9924 unsigned ident = 0;
9925 pthread_mutex_lock(&m_lock);
9926 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9927 while (m_etb_q.m_size) {
9928 m_etb_q.pop_entry(&p1,&p2,&ident);
9929 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9930 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9931 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9932 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9933 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9934 omx_report_error();
9935 }
9936 } else {
9937 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9938 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9939 }
9940 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9941 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9942 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9943 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9944 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9945 omx_report_error ();
9946 }
9947 } else {
9948 pending_input_buffers++;
9949 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9950 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9951 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9952 }
9953 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9954 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9955 (OMX_BUFFERHEADERTYPE *)p1);
9956 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9957 }
9958 }
9959 pthread_mutex_unlock(&m_lock);
9960 }
9961}
9962#endif
Praveen Chavan09a82b72014-10-18 09:09:45 -07009963
9964//static
9965OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
9966
9967#ifndef FLEXYUV_SUPPORTED
9968 (void)pParam;
9969 return OMX_ErrorUndefined;
9970#else
9971
9972 if (pParam == NULL) {
9973 DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
9974 return OMX_ErrorBadParameter;
9975 }
9976
9977 DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
9978
9979 MediaImage *img = &(params->sMediaImage);
9980 switch(params->eColorFormat) {
9981 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
9982 {
9983 img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
9984 img->mNumPlanes = 3;
9985 // mWidth and mHeight represent the W x H of the largest plane
9986 // In our case, this happens to be the Stride x Scanlines of Y plane
9987 img->mWidth = params->nFrameWidth;
9988 img->mHeight = params->nFrameHeight;
9989 size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
9990 size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
9991 img->mBitDepth = 8;
9992 //Plane 0 (Y)
9993 img->mPlane[MediaImage::Y].mOffset = 0;
9994 img->mPlane[MediaImage::Y].mColInc = 1;
9995 img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
9996 img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
9997 img->mPlane[MediaImage::Y].mVertSubsampling = 1;
9998 //Plane 1 (U)
9999 img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
10000 img->mPlane[MediaImage::U].mColInc = 2; //interleaved UV
10001 img->mPlane[MediaImage::U].mRowInc =
10002 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
10003 img->mPlane[MediaImage::U].mHorizSubsampling = 2;
10004 img->mPlane[MediaImage::U].mVertSubsampling = 2;
10005 //Plane 2 (V)
10006 img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
10007 img->mPlane[MediaImage::V].mColInc = 2; //interleaved UV
10008 img->mPlane[MediaImage::V].mRowInc =
10009 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
10010 img->mPlane[MediaImage::V].mHorizSubsampling = 2;
10011 img->mPlane[MediaImage::V].mVertSubsampling = 2;
10012 break;
10013 }
10014
10015 case OMX_COLOR_FormatYUV420Planar:
10016 case OMX_COLOR_FormatYUV420SemiPlanar:
10017 // We need not describe the standard OMX linear formats as these are
10018 // understood by client. Fail this deliberately to let client fill-in
10019 return OMX_ErrorUnsupportedSetting;
10020
10021 default:
10022 // Rest all formats which are non-linear cannot be described
10023 DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
10024 img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
10025 return OMX_ErrorNone;
10026 };
10027
10028 DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
10029 DEBUG_PRINT_LOW(" FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
10030 DEBUG_PRINT_LOW(" YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
10031 for (size_t i = 0; i < img->mNumPlanes; ++i) {
10032 DEBUG_PRINT_LOW(" Plane[%d] : offset=%d / xStep=%d / yStep = %d",
10033 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
10034 }
10035 return OMX_ErrorNone;
10036#endif //FLEXYUV_SUPPORTED
10037}
10038