blob: e7360cb75152c6bee1efbb05817d7e7af7614936 [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;
Praveen Chavan281d5022015-04-30 20:28:44 -07004148 } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) {
4149 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
4150 DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16);
4151
4152 struct v4l2_control control;
4153
4154 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
4155 control.value = rate->nU32;
4156
4157 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
4158 ret = errno == -EBUSY ? OMX_ErrorInsufficientResources :
4159 OMX_ErrorUnsupportedSetting;
4160 DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)",
4161 rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno));
4162 }
4163 return ret;
Arun Menon906de572013-06-18 17:01:40 -07004164 }
4165
4166 return OMX_ErrorNotImplemented;
4167}
4168
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304169#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
4170
Arun Menon906de572013-06-18 17:01:40 -07004171/* ======================================================================
4172 FUNCTION
4173 omx_vdec::GetExtensionIndex
4174
4175 DESCRIPTION
4176 OMX GetExtensionIndex method implementaion. <TBD>
4177
4178 PARAMETERS
4179 <TBD>.
4180
4181 RETURN VALUE
4182 OMX Error None if everything successful.
4183
4184 ========================================================================== */
4185OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
4186 OMX_IN OMX_STRING paramName,
4187 OMX_OUT OMX_INDEXTYPE* indexType)
4188{
4189 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004190 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004191 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304192 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07004193 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304194 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004195 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304196 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
4197 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
4198 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
4199 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08004200 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
4201 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08004202 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
4203 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08004204 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
4205 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004206 }
4207#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304208 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004209 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304210 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004211 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304212 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004213 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004214 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304215 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004216 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4217 }
4218#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304219 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07004220 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
4221 }
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05304222#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Praveen Chavancf924182013-12-06 23:16:23 -08004223 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
4224 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
4225 }
4226#endif
Praveen Chavan09a82b72014-10-18 09:09:45 -07004227#ifdef FLEXYUV_SUPPORTED
4228 else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
4229 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
4230 }
4231#endif
Arun Menon906de572013-06-18 17:01:40 -07004232 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004233 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004234 return OMX_ErrorNotImplemented;
4235 }
4236 return OMX_ErrorNone;
4237}
4238
4239/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004240 FUNCTION
4241 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07004242
Arun Menon906de572013-06-18 17:01:40 -07004243 DESCRIPTION
4244 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004245
Arun Menon906de572013-06-18 17:01:40 -07004246 PARAMETERS
4247 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004248
Arun Menon906de572013-06-18 17:01:40 -07004249 RETURN VALUE
4250 Error None if everything is successful.
4251 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004252OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004253 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004254{
Arun Menon906de572013-06-18 17:01:40 -07004255 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004256 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07004257 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004258}
4259
4260/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004261 FUNCTION
4262 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07004263
Arun Menon906de572013-06-18 17:01:40 -07004264 DESCRIPTION
4265 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004266
Arun Menon906de572013-06-18 17:01:40 -07004267 PARAMETERS
4268 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004269
Arun Menon906de572013-06-18 17:01:40 -07004270 RETURN VALUE
4271 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004272
Arun Menon906de572013-06-18 17:01:40 -07004273 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004274OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004275 OMX_IN OMX_U32 port,
4276 OMX_IN OMX_HANDLETYPE peerComponent,
4277 OMX_IN OMX_U32 peerPort,
4278 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004279{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004280 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07004281 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004282}
4283
4284/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004285 FUNCTION
4286 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004287
Arun Menon906de572013-06-18 17:01:40 -07004288 DESCRIPTION
4289 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004290
Arun Menon906de572013-06-18 17:01:40 -07004291 PARAMETERS
4292 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004293
Arun Menon906de572013-06-18 17:01:40 -07004294 RETURN VALUE
4295 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004296
Arun Menon906de572013-06-18 17:01:40 -07004297 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004298OMX_ERRORTYPE omx_vdec::allocate_extradata()
4299{
4300#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004301 if (drv_ctx.extradata_info.buffer_size) {
4302 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4303 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4304 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4305 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004306 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004307 }
4308 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4309 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4310 drv_ctx.extradata_info.size, 4096,
4311 &drv_ctx.extradata_info.ion.ion_alloc_data,
4312 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4313 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004314 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004315 return OMX_ErrorInsufficientResources;
4316 }
4317 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4318 drv_ctx.extradata_info.size,
4319 PROT_READ|PROT_WRITE, MAP_SHARED,
4320 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4321 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004322 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004323 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4324 free_ion_memory(&drv_ctx.extradata_info.ion);
4325 return OMX_ErrorInsufficientResources;
4326 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004327 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004328#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304329 if (!m_other_extradata) {
4330 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4331 if (!m_other_extradata) {
4332 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4333 return OMX_ErrorInsufficientResources;
4334 }
4335 }
Arun Menon906de572013-06-18 17:01:40 -07004336 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004337}
4338
Arun Menon906de572013-06-18 17:01:40 -07004339void omx_vdec::free_extradata()
4340{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004341#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004342 if (drv_ctx.extradata_info.uaddr) {
4343 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4344 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4345 free_ion_memory(&drv_ctx.extradata_info.ion);
4346 }
4347 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004348#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304349 if (m_other_extradata) {
4350 free(m_other_extradata);
4351 m_other_extradata = NULL;
4352 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004353}
4354
Shalaj Jain273b3e02012-06-22 19:08:03 -07004355OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004356 OMX_IN OMX_HANDLETYPE hComp,
4357 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4358 OMX_IN OMX_U32 port,
4359 OMX_IN OMX_PTR appData,
4360 OMX_IN OMX_U32 bytes,
4361 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004362{
Arun Menon906de572013-06-18 17:01:40 -07004363 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4364 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4365 unsigned i= 0; // Temporary counter
4366 struct vdec_setbuffer_cmd setbuffers;
4367 OMX_PTR privateAppData = NULL;
4368 private_handle_t *handle = NULL;
4369 OMX_U8 *buff = buffer;
4370 struct v4l2_buffer buf;
4371 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4372 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004373
Arun Menon906de572013-06-18 17:01:40 -07004374 if (!m_out_mem_ptr) {
4375 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4376 eRet = allocate_output_headers();
4377 if (eRet == OMX_ErrorNone)
4378 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004379 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004380
Arun Menon906de572013-06-18 17:01:40 -07004381 if (eRet == OMX_ErrorNone) {
4382 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4383 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4384 break;
4385 }
4386 }
4387 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004388
Arun Menon906de572013-06-18 17:01:40 -07004389 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004390 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004391 eRet = OMX_ErrorInsufficientResources;
4392 }
4393
Arun Menonbdb80b02013-08-12 17:45:54 -07004394 if (dynamic_buf_mode) {
4395 *bufferHdr = (m_out_mem_ptr + i );
4396 (*bufferHdr)->pBuffer = NULL;
4397 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4398 enum v4l2_buf_type buf_type;
4399 int rr = 0;
4400 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4401 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4402 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4403 return OMX_ErrorInsufficientResources;
4404 } else {
4405 streaming[CAPTURE_PORT] = true;
4406 DEBUG_PRINT_LOW("STREAMON Successful");
4407 }
4408 }
4409 BITMASK_SET(&m_out_bm_count,i);
4410 (*bufferHdr)->pAppPrivate = appData;
4411 (*bufferHdr)->pBuffer = buffer;
4412 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4413 return eRet;
4414 }
Arun Menon906de572013-06-18 17:01:40 -07004415 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004416#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004417 if (m_enable_android_native_buffers) {
4418 if (m_use_android_native_buffers) {
4419 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4420 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4421 handle = (private_handle_t *)nBuf->handle;
4422 privateAppData = params->pAppPrivate;
4423 } else {
4424 handle = (private_handle_t *)buff;
4425 privateAppData = appData;
4426 }
Arun Menon8544ead2014-05-08 17:42:29 -07004427 if (!handle) {
4428 DEBUG_PRINT_ERROR("handle is invalid");
4429 return OMX_ErrorBadParameter;
4430 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004431
Arun Menon906de572013-06-18 17:01:40 -07004432 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4433 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4434 " expected %u, got %lu",
4435 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4436 return OMX_ErrorBadParameter;
4437 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004438
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07004439 drv_ctx.op_buf.buffer_size = handle->size;
4440
Arun Menon906de572013-06-18 17:01:40 -07004441 if (!m_use_android_native_buffers) {
4442 if (!secure_mode) {
4443 buff = (OMX_U8*)mmap(0, handle->size,
4444 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4445 if (buff == MAP_FAILED) {
4446 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4447 return OMX_ErrorInsufficientResources;
4448 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004449 }
4450 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004451#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004452 native_buffer[i].nativehandle = handle;
4453 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004454#endif
Arun Menon906de572013-06-18 17:01:40 -07004455 if (!handle) {
4456 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4457 return OMX_ErrorBadParameter;
4458 }
4459 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4460 drv_ctx.ptr_outputbuffer[i].offset = 0;
4461 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4462 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4463 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4464 } else
4465#endif
4466
4467 if (!ouput_egl_buffers && !m_use_output_pmem) {
4468#ifdef USE_ION
4469 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4470 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4471 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4472 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4473 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004474 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 -07004475 return OMX_ErrorInsufficientResources;
4476 }
4477 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4478 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4479#else
4480 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4481 open (MEM_DEVICE,O_RDWR);
4482
4483 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004484 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004485 return OMX_ErrorInsufficientResources;
4486 }
4487
4488 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4489 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4490 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4491 open (MEM_DEVICE,O_RDWR);
4492 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004493 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004494 return OMX_ErrorInsufficientResources;
4495 }
4496 }
4497
4498 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4499 drv_ctx.op_buf.buffer_size,
4500 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004501 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004502 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4503 return OMX_ErrorInsufficientResources;
4504 }
4505#endif
4506 if (!secure_mode) {
4507 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4508 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4509 PROT_READ|PROT_WRITE, MAP_SHARED,
4510 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4511 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4512 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4513#ifdef USE_ION
4514 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4515#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004516 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004517 return OMX_ErrorInsufficientResources;
4518 }
4519 }
4520 drv_ctx.ptr_outputbuffer[i].offset = 0;
4521 privateAppData = appData;
4522 } else {
4523
4524 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4525 if (!appData || !bytes ) {
4526 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004527 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004528 return OMX_ErrorBadParameter;
4529 }
4530 }
4531
4532 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4533 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4534 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
Arun Menon8544ead2014-05-08 17:42:29 -07004535 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
Arun Menon906de572013-06-18 17:01:40 -07004536 !pmem_list->nEntries ||
4537 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004538 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004539 return OMX_ErrorBadParameter;
4540 }
4541 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4542 pmem_list->entryList->entry;
4543 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4544 pmem_info->pmem_fd);
4545 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4546 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4547 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4548 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4549 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4550 privateAppData = appData;
4551 }
4552 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4553 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304554 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4555 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4556 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004557
4558 *bufferHdr = (m_out_mem_ptr + i );
4559 if (secure_mode)
4560 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4561 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4562 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4563 sizeof (vdec_bufferpayload));
4564
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004565 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004566 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4567 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4568
4569 buf.index = i;
4570 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4571 buf.memory = V4L2_MEMORY_USERPTR;
4572 plane[0].length = drv_ctx.op_buf.buffer_size;
4573 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4574 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4575 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4576 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4577 plane[0].data_offset = 0;
4578 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4579 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4580 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4581 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4582#ifdef USE_ION
4583 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4584#endif
4585 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4586 plane[extra_idx].data_offset = 0;
4587 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004588 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004589 return OMX_ErrorBadParameter;
4590 }
Arun Menon906de572013-06-18 17:01:40 -07004591 buf.m.planes = plane;
4592 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004593
Arun Menon906de572013-06-18 17:01:40 -07004594 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004595 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004596 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004597 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004598 }
4599
Arun Menon906de572013-06-18 17:01:40 -07004600 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4601 enum v4l2_buf_type buf_type;
4602 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4603 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4604 return OMX_ErrorInsufficientResources;
4605 } else {
4606 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004607 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004608 }
4609 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004610
Arun Menon906de572013-06-18 17:01:40 -07004611 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4612 if (m_enable_android_native_buffers) {
4613 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4614 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4615 } else {
4616 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004617 }
Arun Menon906de572013-06-18 17:01:40 -07004618 (*bufferHdr)->pAppPrivate = privateAppData;
4619 BITMASK_SET(&m_out_bm_count,i);
4620 }
4621 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004622}
4623
4624/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004625 FUNCTION
4626 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004627
Arun Menon906de572013-06-18 17:01:40 -07004628 DESCRIPTION
4629 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004630
Arun Menon906de572013-06-18 17:01:40 -07004631 PARAMETERS
4632 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004633
Arun Menon906de572013-06-18 17:01:40 -07004634 RETURN VALUE
4635 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004636
Arun Menon906de572013-06-18 17:01:40 -07004637 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004638OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004639 OMX_IN OMX_HANDLETYPE hComp,
4640 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4641 OMX_IN OMX_U32 port,
4642 OMX_IN OMX_PTR appData,
4643 OMX_IN OMX_U32 bytes,
4644 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004645{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004646 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004647 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4648 if (!m_inp_heap_ptr)
4649 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4650 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4651 drv_ctx.ip_buf.actualcount);
4652 if (!m_phdr_pmem_ptr)
4653 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4654 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4655 drv_ctx.ip_buf.actualcount);
4656 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4657 DEBUG_PRINT_ERROR("Insufficent memory");
4658 eRet = OMX_ErrorInsufficientResources;
4659 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4660 input_use_buffer = true;
4661 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4662 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4663 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4664 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4665 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4666 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4667 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4668 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004669 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 -07004670 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4671 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004672 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004673 return OMX_ErrorInsufficientResources;
4674 }
4675 m_in_alloc_cnt++;
4676 } else {
4677 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4678 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004679 }
Arun Menon906de572013-06-18 17:01:40 -07004680 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004681}
4682
4683/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004684 FUNCTION
4685 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004686
Arun Menon906de572013-06-18 17:01:40 -07004687 DESCRIPTION
4688 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004689
Arun Menon906de572013-06-18 17:01:40 -07004690 PARAMETERS
4691 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004692
Arun Menon906de572013-06-18 17:01:40 -07004693 RETURN VALUE
4694 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004695
Arun Menon906de572013-06-18 17:01:40 -07004696 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004697OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004698 OMX_IN OMX_HANDLETYPE hComp,
4699 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4700 OMX_IN OMX_U32 port,
4701 OMX_IN OMX_PTR appData,
4702 OMX_IN OMX_U32 bytes,
4703 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004704{
Arun Menon906de572013-06-18 17:01:40 -07004705 OMX_ERRORTYPE error = OMX_ErrorNone;
4706 struct vdec_setbuffer_cmd setbuffers;
4707
Arun Menon8544ead2014-05-08 17:42:29 -07004708 if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
4709 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4710 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004711 }
Arun Menon906de572013-06-18 17:01:40 -07004712 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004713 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004714 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004715 }
Arun Menon906de572013-06-18 17:01:40 -07004716 if (port == OMX_CORE_INPUT_PORT_INDEX)
4717 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4718 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4719 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4720 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004721 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004722 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004723 }
Arun Menon906de572013-06-18 17:01:40 -07004724 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4725 if (error == OMX_ErrorNone) {
4726 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4727 // Send the callback now
4728 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4729 post_event(OMX_CommandStateSet,OMX_StateIdle,
4730 OMX_COMPONENT_GENERATE_EVENT);
4731 }
4732 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4733 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4734 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4735 post_event(OMX_CommandPortEnable,
4736 OMX_CORE_INPUT_PORT_INDEX,
4737 OMX_COMPONENT_GENERATE_EVENT);
4738 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4739 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4740 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4741 post_event(OMX_CommandPortEnable,
4742 OMX_CORE_OUTPUT_PORT_INDEX,
4743 OMX_COMPONENT_GENERATE_EVENT);
4744 }
4745 }
4746 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004747}
4748
4749OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004750 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004751{
Arun Menon906de572013-06-18 17:01:40 -07004752 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4753 if (m_inp_heap_ptr[bufferindex].pBuffer)
4754 free(m_inp_heap_ptr[bufferindex].pBuffer);
4755 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4756 }
4757 if (pmem_bufferHdr)
4758 free_input_buffer(pmem_bufferHdr);
4759 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004760}
4761
4762OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4763{
Arun Menon906de572013-06-18 17:01:40 -07004764 unsigned int index = 0;
4765 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4766 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004767 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004768
Arun Menon906de572013-06-18 17:01:40 -07004769 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004770 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004771
4772 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004773 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004774 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4775 struct vdec_setbuffer_cmd setbuffers;
4776 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4777 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4778 sizeof (vdec_bufferpayload));
4779 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004780 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004781 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004782 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004783 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4784 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4785 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4786 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4787 }
4788 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4789 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4790 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4791 free(m_desc_buffer_ptr[index].buf_addr);
4792 m_desc_buffer_ptr[index].buf_addr = NULL;
4793 m_desc_buffer_ptr[index].desc_data_size = 0;
4794 }
4795#ifdef USE_ION
4796 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4797#endif
4798 }
4799 }
4800
4801 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004802}
4803
4804OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4805{
Arun Menon906de572013-06-18 17:01:40 -07004806 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004807
Arun Menon906de572013-06-18 17:01:40 -07004808 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4809 return OMX_ErrorBadParameter;
4810 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004811
Arun Menon906de572013-06-18 17:01:40 -07004812 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004813 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004814
Arun Menon906de572013-06-18 17:01:40 -07004815 if (index < drv_ctx.op_buf.actualcount
4816 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004817 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004818 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004819
Arun Menon906de572013-06-18 17:01:40 -07004820 struct vdec_setbuffer_cmd setbuffers;
4821 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4822 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4823 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004824
4825 if (!dynamic_buf_mode) {
Balamurugan Alagarsamye773c582014-12-17 15:10:25 +05304826 if (streaming[CAPTURE_PORT] &&
4827 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) {
4828 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
4829 DEBUG_PRINT_ERROR("STREAMOFF Failed");
4830 } else {
4831 DEBUG_PRINT_LOW("STREAMOFF Successful");
4832 }
4833 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004834#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004835 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004836 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004837 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4838 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4839 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4840 }
Arun Menon906de572013-06-18 17:01:40 -07004841 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004842 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4843 } else {
4844#endif
4845 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4846 if (!secure_mode) {
4847 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4848 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4849 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4850 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4851 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4852 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4853 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4854 }
4855 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4856 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004857#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004858 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004859#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004860 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004861#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004862 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004863#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004864 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004865 if (release_output_done()) {
4866 free_extradata();
4867 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004868 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004869
Arun Menon906de572013-06-18 17:01:40 -07004870 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004871
4872}
4873
4874OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004875 OMX_BUFFERHEADERTYPE **bufferHdr,
4876 OMX_U32 port,
4877 OMX_PTR appData,
4878 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004879{
Arun Menon906de572013-06-18 17:01:40 -07004880 OMX_BUFFERHEADERTYPE *input = NULL;
4881 unsigned char *buf_addr = NULL;
4882 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4883 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004884
Arun Menon906de572013-06-18 17:01:40 -07004885 /* Sanity Check*/
4886 if (bufferHdr == NULL) {
4887 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004888 }
4889
Arun Menon906de572013-06-18 17:01:40 -07004890 if (m_inp_heap_ptr == NULL) {
4891 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4892 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4893 drv_ctx.ip_buf.actualcount);
4894 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4895 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4896 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004897
Arun Menon8544ead2014-05-08 17:42:29 -07004898 if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
4899 DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004900 return OMX_ErrorInsufficientResources;
4901 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004902 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004903
Arun Menon906de572013-06-18 17:01:40 -07004904 /*Find a Free index*/
4905 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4906 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004907 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004908 break;
4909 }
4910 }
4911
4912 if (i < drv_ctx.ip_buf.actualcount) {
4913 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4914
4915 if (buf_addr == NULL) {
4916 return OMX_ErrorInsufficientResources;
4917 }
4918
4919 *bufferHdr = (m_inp_heap_ptr + i);
4920 input = *bufferHdr;
4921 BITMASK_SET(&m_heap_inp_bm_count,i);
4922
4923 input->pBuffer = (OMX_U8 *)buf_addr;
4924 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4925 input->nVersion.nVersion = OMX_SPEC_VERSION;
4926 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4927 input->pAppPrivate = appData;
4928 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004929 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004930 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004931 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004932 /*Add the Buffers to freeq*/
4933 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4934 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004935 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004936 return OMX_ErrorInsufficientResources;
4937 }
4938 } else {
4939 return OMX_ErrorBadParameter;
4940 }
4941
4942 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004943
4944}
4945
4946
4947/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004948 FUNCTION
4949 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004950
Arun Menon906de572013-06-18 17:01:40 -07004951 DESCRIPTION
4952 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004953
Arun Menon906de572013-06-18 17:01:40 -07004954 PARAMETERS
4955 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004956
Arun Menon906de572013-06-18 17:01:40 -07004957 RETURN VALUE
4958 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004959
Arun Menon906de572013-06-18 17:01:40 -07004960 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004961OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004962 OMX_IN OMX_HANDLETYPE hComp,
4963 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4964 OMX_IN OMX_U32 port,
4965 OMX_IN OMX_PTR appData,
4966 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004967{
4968
Arun Menon906de572013-06-18 17:01:40 -07004969 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4970 struct vdec_setbuffer_cmd setbuffers;
4971 OMX_BUFFERHEADERTYPE *input = NULL;
4972 unsigned i = 0;
4973 unsigned char *buf_addr = NULL;
4974 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004975
Arun Menon906de572013-06-18 17:01:40 -07004976 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004977 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004978 bytes, drv_ctx.ip_buf.buffer_size);
4979 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004980 }
4981
Arun Menon906de572013-06-18 17:01:40 -07004982 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004983 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004984 drv_ctx.ip_buf.actualcount,
4985 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004986
Arun Menon906de572013-06-18 17:01:40 -07004987 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4988 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4989
4990 if (m_inp_mem_ptr == NULL) {
4991 return OMX_ErrorInsufficientResources;
4992 }
4993
4994 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4995 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4996
4997 if (drv_ctx.ptr_inputbuffer == NULL) {
4998 return OMX_ErrorInsufficientResources;
4999 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005000#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005001 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
5002 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005003
Arun Menon906de572013-06-18 17:01:40 -07005004 if (drv_ctx.ip_buf_ion_info == NULL) {
5005 return OMX_ErrorInsufficientResources;
5006 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005007#endif
5008
Arun Menon906de572013-06-18 17:01:40 -07005009 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
5010 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005011#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005012 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005013#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07005014 }
5015 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005016
Arun Menon906de572013-06-18 17:01:40 -07005017 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
5018 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005019 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005020 break;
5021 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005022 }
Arun Menon906de572013-06-18 17:01:40 -07005023
5024 if (i < drv_ctx.ip_buf.actualcount) {
5025 struct v4l2_buffer buf;
5026 struct v4l2_plane plane;
5027 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005028 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07005029#ifdef USE_ION
5030 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
5031 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
5032 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
5033 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
5034 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
5035 return OMX_ErrorInsufficientResources;
5036 }
5037 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
5038#else
5039 pmem_fd = open (MEM_DEVICE,O_RDWR);
5040
5041 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005042 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005043 return OMX_ErrorInsufficientResources;
5044 }
5045
5046 if (pmem_fd == 0) {
5047 pmem_fd = open (MEM_DEVICE,O_RDWR);
5048
5049 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005050 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005051 return OMX_ErrorInsufficientResources;
5052 }
5053 }
5054
5055 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
5056 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005057 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005058 close(pmem_fd);
5059 return OMX_ErrorInsufficientResources;
5060 }
5061#endif
5062 if (!secure_mode) {
5063 buf_addr = (unsigned char *)mmap(NULL,
5064 drv_ctx.ip_buf.buffer_size,
5065 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
5066
5067 if (buf_addr == MAP_FAILED) {
5068 close(pmem_fd);
5069#ifdef USE_ION
5070 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
5071#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005072 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005073 return OMX_ErrorInsufficientResources;
5074 }
5075 }
5076 *bufferHdr = (m_inp_mem_ptr + i);
5077 if (secure_mode)
5078 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
5079 else
5080 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
5081 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
5082 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
5083 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
5084 drv_ctx.ptr_inputbuffer [i].offset = 0;
5085
5086
5087 buf.index = i;
5088 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5089 buf.memory = V4L2_MEMORY_USERPTR;
5090 plane.bytesused = 0;
5091 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
5092 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
5093 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
5094 plane.reserved[1] = 0;
5095 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
5096 buf.m.planes = &plane;
5097 buf.length = 1;
5098
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005099 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07005100 drv_ctx.ptr_inputbuffer[i].bufferaddr);
5101
5102 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5103
5104 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005105 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07005106 /*TODO: How to handle this case */
5107 return OMX_ErrorInsufficientResources;
5108 }
5109
5110 input = *bufferHdr;
5111 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005112 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07005113 if (secure_mode)
5114 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
5115 else
5116 input->pBuffer = (OMX_U8 *)buf_addr;
5117 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5118 input->nVersion.nVersion = OMX_SPEC_VERSION;
5119 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
5120 input->pAppPrivate = appData;
5121 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
5122 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
5123
5124 if (drv_ctx.disable_dmx) {
5125 eRet = allocate_desc_buffer(i);
5126 }
5127 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005128 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07005129 eRet = OMX_ErrorInsufficientResources;
5130 }
5131 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005132}
5133
5134
5135/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005136 FUNCTION
5137 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005138
Arun Menon906de572013-06-18 17:01:40 -07005139 DESCRIPTION
5140 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07005141
Arun Menon906de572013-06-18 17:01:40 -07005142 PARAMETERS
5143 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005144
Arun Menon906de572013-06-18 17:01:40 -07005145 RETURN VALUE
5146 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005147
Arun Menon906de572013-06-18 17:01:40 -07005148 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005149OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07005150 OMX_IN OMX_HANDLETYPE hComp,
5151 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5152 OMX_IN OMX_U32 port,
5153 OMX_IN OMX_PTR appData,
5154 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005155{
Arun Menon906de572013-06-18 17:01:40 -07005156 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5157 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
5158 unsigned i= 0; // Temporary counter
5159 struct vdec_setbuffer_cmd setbuffers;
5160 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005161#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005162 int ion_device_fd =-1;
5163 struct ion_allocation_data ion_alloc_data;
5164 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005165#endif
Arun Menon906de572013-06-18 17:01:40 -07005166 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005167 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07005168 drv_ctx.op_buf.actualcount,
5169 drv_ctx.op_buf.buffer_size);
5170 int nBufHdrSize = 0;
5171 int nPlatformEntrySize = 0;
5172 int nPlatformListSize = 0;
5173 int nPMEMInfoSize = 0;
5174 int pmem_fd = -1;
5175 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005176
Arun Menon906de572013-06-18 17:01:40 -07005177 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
5178 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
5179 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005180
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005181 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07005182 drv_ctx.op_buf.actualcount);
5183 nBufHdrSize = drv_ctx.op_buf.actualcount *
5184 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005185
Arun Menon906de572013-06-18 17:01:40 -07005186 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
5187 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
5188 nPlatformListSize = drv_ctx.op_buf.actualcount *
5189 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
5190 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
5191 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005192
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005193 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07005194 sizeof(OMX_BUFFERHEADERTYPE),
5195 nPMEMInfoSize,
5196 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005197 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07005198 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005199#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005200 ion_device_fd = alloc_map_ion_memory(
5201 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
5202 drv_ctx.op_buf.alignment,
5203 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
5204 if (ion_device_fd < 0) {
5205 return OMX_ErrorInsufficientResources;
5206 }
5207 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005208#else
Arun Menon906de572013-06-18 17:01:40 -07005209 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005210
Arun Menon906de572013-06-18 17:01:40 -07005211 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005212 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005213 drv_ctx.op_buf.buffer_size);
5214 return OMX_ErrorInsufficientResources;
5215 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005216
Arun Menon906de572013-06-18 17:01:40 -07005217 if (pmem_fd == 0) {
5218 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005219
Arun Menon906de572013-06-18 17:01:40 -07005220 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005221 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005222 drv_ctx.op_buf.buffer_size);
5223 return OMX_ErrorInsufficientResources;
5224 }
5225 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005226
Arun Menon906de572013-06-18 17:01:40 -07005227 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5228 drv_ctx.op_buf.actualcount,
5229 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005230 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005231 close(pmem_fd);
5232 return OMX_ErrorInsufficientResources;
5233 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005234#endif
Arun Menon906de572013-06-18 17:01:40 -07005235 if (!secure_mode) {
5236 pmem_baseaddress = (unsigned char *)mmap(NULL,
5237 (drv_ctx.op_buf.buffer_size *
5238 drv_ctx.op_buf.actualcount),
5239 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5240 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005241 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07005242 drv_ctx.op_buf.buffer_size);
5243 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005244#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005245 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005246#endif
Arun Menon906de572013-06-18 17:01:40 -07005247 return OMX_ErrorInsufficientResources;
5248 }
5249 }
5250 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5251 // Alloc mem for platform specific info
5252 char *pPtr=NULL;
5253 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5254 nPMEMInfoSize,1);
5255 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5256 calloc (sizeof(struct vdec_bufferpayload),
5257 drv_ctx.op_buf.actualcount);
5258 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5259 calloc (sizeof (struct vdec_output_frameinfo),
5260 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005261 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
5262 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
5263 return OMX_ErrorInsufficientResources;
5264 }
5265
Arun Menon906de572013-06-18 17:01:40 -07005266#ifdef USE_ION
5267 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5268 calloc (sizeof(struct vdec_ion),
5269 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005270 if (!drv_ctx.op_buf_ion_info) {
5271 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
5272 return OMX_ErrorInsufficientResources;
5273 }
Arun Menon906de572013-06-18 17:01:40 -07005274#endif
5275
5276 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5277 && drv_ctx.ptr_respbuffer) {
5278 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5279 (drv_ctx.op_buf.buffer_size *
5280 drv_ctx.op_buf.actualcount);
5281 bufHdr = m_out_mem_ptr;
5282 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5283 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5284 (((char *) m_platform_list) + nPlatformListSize);
5285 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5286 (((char *) m_platform_entry) + nPlatformEntrySize);
5287 pPlatformList = m_platform_list;
5288 pPlatformEntry = m_platform_entry;
5289 pPMEMInfo = m_pmem_info;
5290
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005291 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07005292
5293 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005294 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
5295 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07005296 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
5297 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5298 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5299 // Set the values when we determine the right HxW param
5300 bufHdr->nAllocLen = bytes;
5301 bufHdr->nFilledLen = 0;
5302 bufHdr->pAppPrivate = appData;
5303 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5304 // Platform specific PMEM Information
5305 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005306 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005307 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5308 pPlatformEntry->entry = pPMEMInfo;
5309 // Initialize the Platform List
5310 pPlatformList->nEntries = 1;
5311 pPlatformList->entryList = pPlatformEntry;
5312 // Keep pBuffer NULL till vdec is opened
5313 bufHdr->pBuffer = NULL;
5314 bufHdr->nOffset = 0;
5315
5316 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5317 pPMEMInfo->pmem_fd = 0;
5318 bufHdr->pPlatformPrivate = pPlatformList;
5319
5320 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5321 m_pmem_info[i].pmem_fd = pmem_fd;
5322#ifdef USE_ION
5323 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5324 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5325 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5326#endif
5327
5328 /*Create a mapping between buffers*/
5329 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5330 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5331 &drv_ctx.ptr_outputbuffer[i];
5332 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5333 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5334 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305335 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5336 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5337 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005338
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005339 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005340 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5341 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5342 // Move the buffer and buffer header pointers
5343 bufHdr++;
5344 pPMEMInfo++;
5345 pPlatformEntry++;
5346 pPlatformList++;
5347 }
5348 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005349 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005350 m_out_mem_ptr, pPtr);
5351 if (m_out_mem_ptr) {
5352 free(m_out_mem_ptr);
5353 m_out_mem_ptr = NULL;
5354 }
5355 if (pPtr) {
5356 free(pPtr);
5357 pPtr = NULL;
5358 }
5359 if (drv_ctx.ptr_outputbuffer) {
5360 free(drv_ctx.ptr_outputbuffer);
5361 drv_ctx.ptr_outputbuffer = NULL;
5362 }
5363 if (drv_ctx.ptr_respbuffer) {
5364 free(drv_ctx.ptr_respbuffer);
5365 drv_ctx.ptr_respbuffer = NULL;
5366 }
5367#ifdef USE_ION
5368 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005369 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005370 free(drv_ctx.op_buf_ion_info);
5371 drv_ctx.op_buf_ion_info = NULL;
5372 }
5373#endif
5374 eRet = OMX_ErrorInsufficientResources;
5375 }
5376 if (eRet == OMX_ErrorNone)
5377 eRet = allocate_extradata();
5378 }
5379
5380 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5381 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005382 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005383 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005384 }
5385 }
Arun Menon906de572013-06-18 17:01:40 -07005386
5387 if (eRet == OMX_ErrorNone) {
5388 if (i < drv_ctx.op_buf.actualcount) {
5389 struct v4l2_buffer buf;
5390 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5391 int rc;
5392 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5393
5394 drv_ctx.ptr_outputbuffer[i].buffer_len =
5395 drv_ctx.op_buf.buffer_size;
5396
5397 *bufferHdr = (m_out_mem_ptr + i );
5398 if (secure_mode) {
5399 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5400 }
5401 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5402
5403 buf.index = i;
5404 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5405 buf.memory = V4L2_MEMORY_USERPTR;
5406 plane[0].length = drv_ctx.op_buf.buffer_size;
5407 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5408 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005409#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005410 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005411#endif
Arun Menon906de572013-06-18 17:01:40 -07005412 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5413 plane[0].data_offset = 0;
5414 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5415 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5416 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5417 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 -07005418#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005419 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005420#endif
Arun Menon906de572013-06-18 17:01:40 -07005421 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5422 plane[extra_idx].data_offset = 0;
5423 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005424 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005425 return OMX_ErrorBadParameter;
5426 }
5427 buf.m.planes = plane;
5428 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005429 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 -07005430 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5431 if (rc) {
5432 /*TODO: How to handle this case */
5433 return OMX_ErrorInsufficientResources;
5434 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005435
Arun Menon906de572013-06-18 17:01:40 -07005436 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5437 enum v4l2_buf_type buf_type;
5438 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5439 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5440 if (rc) {
5441 return OMX_ErrorInsufficientResources;
5442 } else {
5443 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005444 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005445 }
5446 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005447
Arun Menon906de572013-06-18 17:01:40 -07005448 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5449 (*bufferHdr)->pAppPrivate = appData;
5450 BITMASK_SET(&m_out_bm_count,i);
5451 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005452 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005453 eRet = OMX_ErrorInsufficientResources;
5454 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005455 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005456
Arun Menon906de572013-06-18 17:01:40 -07005457 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005458}
5459
5460
5461// AllocateBuffer -- API Call
5462/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005463 FUNCTION
5464 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005465
Arun Menon906de572013-06-18 17:01:40 -07005466 DESCRIPTION
5467 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005468
Arun Menon906de572013-06-18 17:01:40 -07005469 PARAMETERS
5470 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005471
Arun Menon906de572013-06-18 17:01:40 -07005472 RETURN VALUE
5473 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005474
Arun Menon906de572013-06-18 17:01:40 -07005475 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005476OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005477 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5478 OMX_IN OMX_U32 port,
5479 OMX_IN OMX_PTR appData,
5480 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005481{
5482 unsigned i = 0;
5483 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5484
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005485 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005486 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005487 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005488 return OMX_ErrorInvalidState;
5489 }
5490
Arun Menon906de572013-06-18 17:01:40 -07005491 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5492 if (arbitrary_bytes) {
5493 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5494 } else {
5495 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5496 }
5497 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005498 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5499 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005500 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005501 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005502 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005503 }
5504 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005505 if (eRet == OMX_ErrorNone) {
5506 if (allocate_done()) {
5507 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005508 // Send the callback now
5509 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5510 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005511 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005512 }
5513 }
Arun Menon906de572013-06-18 17:01:40 -07005514 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5515 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5516 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5517 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005518 OMX_CORE_INPUT_PORT_INDEX,
5519 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005520 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005521 }
Arun Menon906de572013-06-18 17:01:40 -07005522 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5523 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5524 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005525 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005526 OMX_CORE_OUTPUT_PORT_INDEX,
5527 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005528 }
5529 }
5530 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005531 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005532 return eRet;
5533}
5534
5535// Free Buffer - API call
5536/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005537 FUNCTION
5538 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005539
Arun Menon906de572013-06-18 17:01:40 -07005540 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005541
Arun Menon906de572013-06-18 17:01:40 -07005542 PARAMETERS
5543 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005544
Arun Menon906de572013-06-18 17:01:40 -07005545 RETURN VALUE
5546 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005547
Arun Menon906de572013-06-18 17:01:40 -07005548 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005549OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005550 OMX_IN OMX_U32 port,
5551 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005552{
5553 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5554 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005555 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005556
Arun Menon906de572013-06-18 17:01:40 -07005557 if (m_state == OMX_StateIdle &&
5558 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005559 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005560 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5561 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005562 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005563 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5564 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5565 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5566 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005567 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005568 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005569 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005570 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005571 OMX_ErrorPortUnpopulated,
5572 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005573
5574 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005575 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005576 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005577 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005578 OMX_ErrorPortUnpopulated,
5579 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005580 }
5581
Arun Menon906de572013-06-18 17:01:40 -07005582 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5583 /*Check if arbitrary bytes*/
5584 if (!arbitrary_bytes && !input_use_buffer)
5585 nPortIndex = buffer - m_inp_mem_ptr;
5586 else
5587 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005588
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005589 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005590 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5591 // Clear the bit associated with it.
5592 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5593 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5594 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005595
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005596 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005597 if (m_phdr_pmem_ptr)
5598 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5599 } else {
5600 if (arbitrary_bytes) {
5601 if (m_phdr_pmem_ptr)
5602 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5603 else
5604 free_input_buffer(nPortIndex,NULL);
5605 } else
5606 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005607 }
Arun Menon906de572013-06-18 17:01:40 -07005608 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305609 if(release_input_done())
5610 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005611 /*Free the Buffer Header*/
5612 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005613 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005614 free_input_buffer_header();
5615 }
5616 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005617 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005618 eRet = OMX_ErrorBadPortIndex;
5619 }
5620
Arun Menon906de572013-06-18 17:01:40 -07005621 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5622 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005623 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005624 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5625 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005626 OMX_CORE_INPUT_PORT_INDEX,
5627 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005628 }
Arun Menon906de572013-06-18 17:01:40 -07005629 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005630 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005631 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005632 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005633 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005634 // Clear the bit associated with it.
5635 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5636 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005637 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005638
Surajit Podder12aefac2013-08-06 18:43:32 +05305639 if(release_output_done()) {
5640 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5641 }
Arun Menon906de572013-06-18 17:01:40 -07005642 if (release_output_done()) {
5643 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005644 }
Arun Menon906de572013-06-18 17:01:40 -07005645 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005646 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005647 eRet = OMX_ErrorBadPortIndex;
5648 }
Arun Menon906de572013-06-18 17:01:40 -07005649 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5650 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005651 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005652
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005653 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005654 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005655#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005656 if (m_enable_android_native_buffers) {
5657 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5658 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5659 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005660#endif
5661
Arun Menon906de572013-06-18 17:01:40 -07005662 post_event(OMX_CommandPortDisable,
5663 OMX_CORE_OUTPUT_PORT_INDEX,
5664 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005665 }
Arun Menon906de572013-06-18 17:01:40 -07005666 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005667 eRet = OMX_ErrorBadPortIndex;
5668 }
Arun Menon906de572013-06-18 17:01:40 -07005669 if ((eRet == OMX_ErrorNone) &&
5670 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5671 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005672 // Send the callback now
5673 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5674 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005675 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005676 }
5677 }
5678 return eRet;
5679}
5680
5681
5682/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005683 FUNCTION
5684 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005685
Arun Menon906de572013-06-18 17:01:40 -07005686 DESCRIPTION
5687 This routine is used to push the encoded video frames to
5688 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005689
Arun Menon906de572013-06-18 17:01:40 -07005690 PARAMETERS
5691 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005692
Arun Menon906de572013-06-18 17:01:40 -07005693 RETURN VALUE
5694 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005695
Arun Menon906de572013-06-18 17:01:40 -07005696 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005697OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005698 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005699{
Arun Menon906de572013-06-18 17:01:40 -07005700 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5701 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005702
Arun Menon906de572013-06-18 17:01:40 -07005703 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005704 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005705 return OMX_ErrorInvalidState;
5706 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005707
Arun Menon906de572013-06-18 17:01:40 -07005708 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005709 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005710 return OMX_ErrorBadParameter;
5711 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005712
Arun Menon906de572013-06-18 17:01:40 -07005713 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005714 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005715 return OMX_ErrorIncorrectStateOperation;
5716 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005717
Arun Menon906de572013-06-18 17:01:40 -07005718 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005719 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005720 return OMX_ErrorBadPortIndex;
5721 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005722
5723#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005724 if (iDivXDrmDecrypt) {
5725 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5726 if (drmErr != OMX_ErrorNone) {
5727 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005728 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005729 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005730 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005731#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005732 if (perf_flag) {
5733 if (!latency) {
5734 dec_time.stop();
5735 latency = dec_time.processing_time_us();
5736 dec_time.start();
5737 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005738 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005739
Arun Menon906de572013-06-18 17:01:40 -07005740 if (arbitrary_bytes) {
5741 nBufferIndex = buffer - m_inp_heap_ptr;
5742 } else {
5743 if (input_use_buffer == true) {
5744 nBufferIndex = buffer - m_inp_heap_ptr;
5745 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5746 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5747 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5748 buffer = &m_inp_mem_ptr[nBufferIndex];
5749 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5750 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5751 } else {
5752 nBufferIndex = buffer - m_inp_mem_ptr;
5753 }
5754 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005755
Arun Menon906de572013-06-18 17:01:40 -07005756 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005757 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005758 return OMX_ErrorBadParameter;
5759 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005760
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005761 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5762 codec_config_flag = true;
5763 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5764 }
5765
Arun Menon906de572013-06-18 17:01:40 -07005766 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5767 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5768 if (arbitrary_bytes) {
5769 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005770 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005771 } else {
Arun Menon906de572013-06-18 17:01:40 -07005772 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5773 }
Praveen Chavanece713f2014-12-10 18:00:04 -08005774 time_stamp_dts.insert_timestamp(buffer);
Arun Menon906de572013-06-18 17:01:40 -07005775 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005776}
5777
5778/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005779 FUNCTION
5780 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005781
Arun Menon906de572013-06-18 17:01:40 -07005782 DESCRIPTION
5783 This routine is used to push the encoded video frames to
5784 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005785
Arun Menon906de572013-06-18 17:01:40 -07005786 PARAMETERS
5787 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005788
Arun Menon906de572013-06-18 17:01:40 -07005789 RETURN VALUE
5790 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005791
Arun Menon906de572013-06-18 17:01:40 -07005792 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005793OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005794 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005795{
Arun Menon906de572013-06-18 17:01:40 -07005796 int push_cnt = 0,i=0;
5797 unsigned nPortIndex = 0;
5798 OMX_ERRORTYPE ret = OMX_ErrorNone;
5799 struct vdec_input_frameinfo frameinfo;
5800 struct vdec_bufferpayload *temp_buffer;
5801 struct vdec_seqheader seq_header;
5802 bool port_setting_changed = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005803
Arun Menon906de572013-06-18 17:01:40 -07005804 /*Should we generate a Aync error event*/
5805 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005806 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005807 return OMX_ErrorBadParameter;
5808 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005809
Arun Menon906de572013-06-18 17:01:40 -07005810 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005811
Arun Menon906de572013-06-18 17:01:40 -07005812 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005813 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005814 nPortIndex);
5815 return OMX_ErrorBadParameter;
5816 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005817
Arun Menon906de572013-06-18 17:01:40 -07005818 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005819
Arun Menon906de572013-06-18 17:01:40 -07005820 /* return zero length and not an EOS buffer */
5821 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5822 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005823 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005824 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5825 OMX_COMPONENT_GENERATE_EBD);
5826 return OMX_ErrorNone;
5827 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005828
c_sridur0af9cef2015-02-05 12:07:17 +05305829 if (input_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005830 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005831 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5832 OMX_COMPONENT_GENERATE_EBD);
5833 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005834 }
5835
Arun Menon906de572013-06-18 17:01:40 -07005836 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005837
Surajit Podderd2644d52013-08-28 17:59:06 +05305838 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005839 return OMX_ErrorBadParameter;
5840 }
5841 /* If its first frame, H264 codec and reject is true, then parse the nal
5842 and get the profile. Based on this, reject the clip playback */
5843 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5844 m_reject_avc_1080p_mp) {
5845 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005846 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005847 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5848 NALU_TYPE_SPS);
5849 m_profile = h264_parser->get_profile();
5850 ret = is_video_session_supported();
5851 if (ret) {
5852 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5853 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5854 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5855 m_state = OMX_StateInvalid;
5856 return OMX_ErrorNone;
5857 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005858 }
5859
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005860 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005861 /*for use buffer we need to memcpy the data*/
5862 temp_buffer->buffer_len = buffer->nFilledLen;
5863
5864 if (input_use_buffer) {
5865 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5866 if (arbitrary_bytes) {
5867 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5868 } else {
5869 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5870 buffer->nFilledLen);
5871 }
5872 } else {
5873 return OMX_ErrorBadParameter;
5874 }
5875
5876 }
5877
5878 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5879 frameinfo.client_data = (void *) buffer;
5880 frameinfo.datalen = temp_buffer->buffer_len;
5881 frameinfo.flags = 0;
5882 frameinfo.offset = buffer->nOffset;
5883 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5884 frameinfo.pmem_offset = temp_buffer->offset;
5885 frameinfo.timestamp = buffer->nTimeStamp;
5886 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5887 DEBUG_PRINT_LOW("ETB: dmx enabled");
5888 if (m_demux_entries == 0) {
5889 extract_demux_addr_offsets(buffer);
5890 }
5891
5892 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5893 handle_demux_data(buffer);
5894 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5895 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5896 } else {
5897 frameinfo.desc_addr = NULL;
5898 frameinfo.desc_size = 0;
5899 }
5900 if (!arbitrary_bytes) {
5901 frameinfo.flags |= buffer->nFlags;
5902 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005903
5904#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005905 if (m_debug_timestamp) {
5906 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005907 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005908 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5909 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005910 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005911 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5912 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005913 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005914#endif
5915
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005916log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005917
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005918if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005919 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5920 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5921 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005922
Arun Menon906de572013-06-18 17:01:40 -07005923 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005924 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005925 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5926 h264_scratch.nFilledLen = 0;
5927 nal_count = 0;
5928 look_ahead_nal = false;
5929 frame_count = 0;
5930 if (m_frame_parser.mutils)
5931 m_frame_parser.mutils->initialize_frame_checking_environment();
5932 m_frame_parser.flush();
5933 h264_last_au_ts = LLONG_MAX;
5934 h264_last_au_flags = 0;
5935 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5936 m_demux_entries = 0;
5937 }
5938 struct v4l2_buffer buf;
5939 struct v4l2_plane plane;
5940 memset( (void *)&buf, 0, sizeof(buf));
5941 memset( (void *)&plane, 0, sizeof(plane));
5942 int rc;
5943 unsigned long print_count;
5944 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005945 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005946 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005947 }
5948 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5949 buf.index = nPortIndex;
5950 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5951 buf.memory = V4L2_MEMORY_USERPTR;
5952 plane.bytesused = temp_buffer->buffer_len;
5953 plane.length = drv_ctx.ip_buf.buffer_size;
5954 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5955 (unsigned long)temp_buffer->offset;
5956 plane.reserved[0] = temp_buffer->pmem_fd;
5957 plane.reserved[1] = temp_buffer->offset;
5958 plane.data_offset = 0;
5959 buf.m.planes = &plane;
5960 buf.length = 1;
5961 if (frameinfo.timestamp >= LLONG_MAX) {
5962 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5963 }
5964 //assumption is that timestamp is in milliseconds
5965 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5966 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5967 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5968 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005969
Pushkaraj Patil20bd6bf2014-12-22 19:33:08 +05305970 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5971 DEBUG_PRINT_LOW("Increment codec_config buffer counter");
5972 android_atomic_inc(&m_queued_codec_config_count);
5973 }
5974
Arun Menon906de572013-06-18 17:01:40 -07005975 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5976 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005977 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005978 return OMX_ErrorHardware;
5979 }
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -07005980
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005981 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5982 codec_config_flag = false;
5983 }
Arun Menon906de572013-06-18 17:01:40 -07005984 if (!streaming[OUTPUT_PORT]) {
5985 enum v4l2_buf_type buf_type;
5986 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005987
Arun Menon906de572013-06-18 17:01:40 -07005988 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005989 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005990 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5991 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005992 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005993 streaming[OUTPUT_PORT] = true;
Jia Meng1e236c82014-04-03 10:54:39 +08005994 } else if (errno == EBUSY) {
5995 DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
5996 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
5997 OMX_COMPONENT_GENERATE_EBD);
5998 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005999 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006000 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07006001 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
Jia Meng1e236c82014-04-03 10:54:39 +08006002 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
Arun Menon906de572013-06-18 17:01:40 -07006003 OMX_COMPONENT_GENERATE_EBD);
6004 return OMX_ErrorBadParameter;
6005 }
6006 }
6007 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
6008 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006009
Arun Menon906de572013-06-18 17:01:40 -07006010 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006011}
6012
6013/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006014 FUNCTION
6015 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07006016
Arun Menon906de572013-06-18 17:01:40 -07006017 DESCRIPTION
6018 IL client uses this method to release the frame buffer
6019 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006020
Arun Menon906de572013-06-18 17:01:40 -07006021 PARAMETERS
6022 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006023
Arun Menon906de572013-06-18 17:01:40 -07006024 RETURN VALUE
6025 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006026
Arun Menon906de572013-06-18 17:01:40 -07006027 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006028OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006029 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006030{
Jia Meng2d51b932014-07-10 14:02:54 +08006031 unsigned nPortIndex = 0;
Arun Menonbdb80b02013-08-12 17:45:54 -07006032 if (dynamic_buf_mode) {
6033 private_handle_t *handle = NULL;
6034 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07006035 unsigned int nPortIndex = 0;
6036
6037 if (!buffer || !buffer->pBuffer) {
Arun Menon8544ead2014-05-08 17:42:29 -07006038 DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
Arun Menonbdb80b02013-08-12 17:45:54 -07006039 return OMX_ErrorBadParameter;
6040 }
6041
6042 //get the buffer type and fd info
6043 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
6044 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08006045 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
6046
6047 if (!handle) {
6048 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
6049 return OMX_ErrorBadParameter;
6050 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006051 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
6052 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6053 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08006054 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006055
6056 //Store private handle from GraphicBuffer
6057 native_buffer[nPortIndex].privatehandle = handle;
6058 native_buffer[nPortIndex].nativehandle = handle;
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006059
6060 //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
6061 //this with a more sane size so that we don't compensate in rest of code
6062 //We'll restore this size later on, so that it's transparent to client
6063 buffer->nFilledLen = 0;
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07006064 buffer->nAllocLen = handle->size;
Arun Menonbdb80b02013-08-12 17:45:54 -07006065 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006066
Arun Menon906de572013-06-18 17:01:40 -07006067 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006068 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07006069 return OMX_ErrorInvalidState;
6070 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006071
Arun Menon906de572013-06-18 17:01:40 -07006072 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006073 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07006074 return OMX_ErrorIncorrectStateOperation;
6075 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006076
Jia Meng2d51b932014-07-10 14:02:54 +08006077 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07006078 if (buffer == NULL ||
Jia Meng2d51b932014-07-10 14:02:54 +08006079 (nPortIndex >= drv_ctx.op_buf.actualcount)) {
6080 DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
6081 nPortIndex, drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07006082 return OMX_ErrorBadParameter;
6083 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006084
Arun Menon906de572013-06-18 17:01:40 -07006085 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006086 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07006087 return OMX_ErrorBadPortIndex;
6088 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006089
Arun Menon906de572013-06-18 17:01:40 -07006090 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6091 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
6092 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006093}
6094/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006095 FUNCTION
6096 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07006097
Arun Menon906de572013-06-18 17:01:40 -07006098 DESCRIPTION
6099 IL client uses this method to release the frame buffer
6100 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006101
Arun Menon906de572013-06-18 17:01:40 -07006102 PARAMETERS
6103 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006104
Arun Menon906de572013-06-18 17:01:40 -07006105 RETURN VALUE
6106 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006107
Arun Menon906de572013-06-18 17:01:40 -07006108 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006109OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07006110 OMX_IN OMX_HANDLETYPE hComp,
6111 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006112{
Arun Menon906de572013-06-18 17:01:40 -07006113 OMX_ERRORTYPE nRet = OMX_ErrorNone;
6114 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
6115 unsigned nPortIndex = 0;
6116 struct vdec_fillbuffer_cmd fillbuffer;
6117 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
6118 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006119
Arun Menon906de572013-06-18 17:01:40 -07006120 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07006121
Jia Meng2d51b932014-07-10 14:02:54 +08006122 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) {
6123 DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
6124 nPortIndex, drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07006125 return OMX_ErrorBadParameter;
Jia Meng2d51b932014-07-10 14:02:54 +08006126 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006127
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006128 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006129 bufferAdd, bufferAdd->pBuffer);
6130 /*Return back the output buffer to client*/
6131 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006132 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07006133 buffer->nFilledLen = 0;
6134 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6135 return OMX_ErrorNone;
6136 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08006137
6138 if (dynamic_buf_mode) {
6139 //map the buffer handle based on the size set on output port definition.
6140 if (!secure_mode) {
6141 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
6142 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
6143 PROT_READ|PROT_WRITE, MAP_SHARED,
6144 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
6145 }
6146 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
6147 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
6148 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
6149 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
6150 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
6151 }
6152
Arun Menon906de572013-06-18 17:01:40 -07006153 pending_output_buffers++;
6154 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
6155 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
6156 if (ptr_respbuffer) {
6157 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
6158 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006159
Arun Menon906de572013-06-18 17:01:40 -07006160 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
6161 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
6162 buffer->nFilledLen = 0;
6163 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6164 pending_output_buffers--;
6165 return OMX_ErrorBadParameter;
6166 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006167
Arun Menon906de572013-06-18 17:01:40 -07006168 int rc = 0;
6169 struct v4l2_buffer buf;
6170 struct v4l2_plane plane[VIDEO_MAX_PLANES];
6171 memset( (void *)&buf, 0, sizeof(buf));
6172 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Arun Menon8544ead2014-05-08 17:42:29 -07006173 unsigned int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006174
Arun Menon906de572013-06-18 17:01:40 -07006175 buf.index = nPortIndex;
6176 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6177 buf.memory = V4L2_MEMORY_USERPTR;
6178 plane[0].bytesused = buffer->nFilledLen;
6179 plane[0].length = drv_ctx.op_buf.buffer_size;
6180 plane[0].m.userptr =
6181 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
6182 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6183 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
6184 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6185 plane[0].data_offset = 0;
6186 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
6187 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
6188 plane[extra_idx].bytesused = 0;
6189 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
6190 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 -07006191#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07006192 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006193#endif
Arun Menon906de572013-06-18 17:01:40 -07006194 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
6195 plane[extra_idx].data_offset = 0;
6196 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Arun Menon8544ead2014-05-08 17:42:29 -07006197 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07006198 return OMX_ErrorBadParameter;
6199 }
6200 buf.m.planes = plane;
6201 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006202 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07006203 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
6204
Arun Menon906de572013-06-18 17:01:40 -07006205 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6206 if (rc) {
6207 /*TODO: How to handle this case */
6208 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6209 }
Arun Menon906de572013-06-18 17:01:40 -07006210return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006211}
6212
6213/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006214 FUNCTION
6215 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07006216
Arun Menon906de572013-06-18 17:01:40 -07006217 DESCRIPTION
6218 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006219
Arun Menon906de572013-06-18 17:01:40 -07006220 PARAMETERS
6221 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006222
Arun Menon906de572013-06-18 17:01:40 -07006223 RETURN VALUE
6224 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006225
Arun Menon906de572013-06-18 17:01:40 -07006226 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006227OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006228 OMX_IN OMX_CALLBACKTYPE* callbacks,
6229 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006230{
6231
Arun Menon906de572013-06-18 17:01:40 -07006232 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006233 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07006234 m_cb.EventHandler,m_cb.FillBufferDone);
6235 m_app_data = appData;
6236 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006237}
6238
6239/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006240 FUNCTION
6241 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07006242
Arun Menon906de572013-06-18 17:01:40 -07006243 DESCRIPTION
6244 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006245
Arun Menon906de572013-06-18 17:01:40 -07006246 PARAMETERS
6247 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006248
Arun Menon906de572013-06-18 17:01:40 -07006249 RETURN VALUE
6250 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006251
Arun Menon906de572013-06-18 17:01:40 -07006252 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006253OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6254{
6255#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006256 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006257 delete iDivXDrmDecrypt;
6258 iDivXDrmDecrypt=NULL;
6259 }
6260#endif //_ANDROID_
6261
Shalaj Jain286b0062013-02-21 20:35:48 -08006262 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07006263 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006264 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07006265 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006266 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07006267 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006268 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006269 }
6270
6271 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006272 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006273 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07006274 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
6275 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006276 }
6277#ifdef _ANDROID_ICS_
6278 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6279#endif
6280 }
6281
6282 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006283 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006284 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07006285 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
6286 if (m_inp_mem_ptr)
6287 free_input_buffer (i,&m_inp_mem_ptr[i]);
6288 else
6289 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006290 }
6291 }
6292 free_input_buffer_header();
6293 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07006294 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006295 free(h264_scratch.pBuffer);
6296 h264_scratch.pBuffer = NULL;
6297 }
6298
Arun Menon906de572013-06-18 17:01:40 -07006299 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006300 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07006301 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006302 }
6303
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006304 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006305 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006306 delete (m_frame_parser.mutils);
6307 m_frame_parser.mutils = NULL;
6308 }
6309
Arun Menon906de572013-06-18 17:01:40 -07006310 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006311 free(m_platform_list);
6312 m_platform_list = NULL;
6313 }
Arun Menon906de572013-06-18 17:01:40 -07006314 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006315 free(m_vendor_config.pData);
6316 m_vendor_config.pData = NULL;
6317 }
6318
6319 // Reset counters in mesg queues
6320 m_ftb_q.m_size=0;
6321 m_cmd_q.m_size=0;
6322 m_etb_q.m_size=0;
6323 m_ftb_q.m_read = m_ftb_q.m_write =0;
6324 m_cmd_q.m_read = m_cmd_q.m_write =0;
6325 m_etb_q.m_read = m_etb_q.m_write =0;
6326#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006327 if (m_debug_timestamp) {
6328 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006329 }
6330#endif
6331
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006332 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006333 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006334 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006335 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006336
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006337 if (m_debug.infile) {
6338 fclose(m_debug.infile);
6339 m_debug.infile = NULL;
6340 }
6341 if (m_debug.outfile) {
6342 fclose(m_debug.outfile);
6343 m_debug.outfile = NULL;
6344 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006345#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006346 if (outputExtradataFile)
6347 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006348#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006349 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006350 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006351}
6352
6353/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006354 FUNCTION
6355 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006356
Arun Menon906de572013-06-18 17:01:40 -07006357 DESCRIPTION
6358 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006359
Arun Menon906de572013-06-18 17:01:40 -07006360 PARAMETERS
6361 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006362
Arun Menon906de572013-06-18 17:01:40 -07006363 RETURN VALUE
6364 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006365
Arun Menon906de572013-06-18 17:01:40 -07006366 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006367OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006368 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6369 OMX_IN OMX_U32 port,
6370 OMX_IN OMX_PTR appData,
6371 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006372{
Arun Menon906de572013-06-18 17:01:40 -07006373 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6374 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6375 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006376
6377#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006378 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6379 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006380#else
Arun Menon906de572013-06-18 17:01:40 -07006381 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006382#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006383 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006384 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006385 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006386 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006387#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006388 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006389 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006390 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006391 }
6392 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6393 eglGetProcAddress("eglQueryImageKHR");
6394 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6395 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6396 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006397#else //with OMX test app
6398 struct temp_egl {
6399 int pmem_fd;
6400 int offset;
6401 };
6402 struct temp_egl *temp_egl_id = NULL;
6403 void * pmemPtr = (void *) eglImage;
6404 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006405 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006406 fd = temp_egl_id->pmem_fd;
6407 offset = temp_egl_id->offset;
6408 }
6409#endif
6410 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006411 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006412 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006413 }
6414 pmem_info.pmem_fd = (OMX_U32) fd;
6415 pmem_info.offset = (OMX_U32) offset;
6416 pmem_entry.entry = (void *) &pmem_info;
6417 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6418 pmem_list.entryList = &pmem_entry;
6419 pmem_list.nEntries = 1;
6420 ouput_egl_buffers = true;
6421 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6422 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6423 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006424 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006425 return OMX_ErrorInsufficientResources;
6426 }
6427 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006428}
6429
6430/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006431 FUNCTION
6432 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006433
Arun Menon906de572013-06-18 17:01:40 -07006434 DESCRIPTION
6435 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006436
Arun Menon906de572013-06-18 17:01:40 -07006437 PARAMETERS
6438 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006439
Arun Menon906de572013-06-18 17:01:40 -07006440 RETURN VALUE
6441 OMX Error None if everything is successful.
6442 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006443OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006444 OMX_OUT OMX_U8* role,
6445 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006446{
Arun Menon906de572013-06-18 17:01:40 -07006447 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006448
Arun Menon906de572013-06-18 17:01:40 -07006449 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6450 if ((0 == index) && role) {
6451 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006452 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006453 } else {
6454 eRet = OMX_ErrorNoMore;
6455 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006456 }
Arun Menon906de572013-06-18 17:01:40 -07006457 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6458 if ((0 == index) && role) {
6459 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006460 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006461 } else {
6462 eRet = OMX_ErrorNoMore;
6463 }
6464 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6465 if ((0 == index) && role) {
6466 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006467 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006468 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006469 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006470 eRet = OMX_ErrorNoMore;
6471 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006472 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006473
Arun Menon906de572013-06-18 17:01:40 -07006474 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6475 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6476 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006477
Shalaj Jain273b3e02012-06-22 19:08:03 -07006478 {
Arun Menon906de572013-06-18 17:01:40 -07006479 if ((0 == index) && role) {
6480 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006481 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006482 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006483 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006484 eRet = OMX_ErrorNoMore;
6485 }
6486 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6487 if ((0 == index) && role) {
6488 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006489 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006490 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006491 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006492 eRet = OMX_ErrorNoMore;
6493 }
6494 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6495 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6496 ) {
6497 if ((0 == index) && role) {
6498 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006499 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006500 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006501 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006502 eRet = OMX_ErrorNoMore;
6503 }
6504 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6505 if ((0 == index) && role) {
6506 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006507 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006508 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006509 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006510 eRet = OMX_ErrorNoMore;
6511 }
6512 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006513 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006514 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006515 }
Arun Menon906de572013-06-18 17:01:40 -07006516 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006517}
6518
6519
6520
6521
6522/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006523 FUNCTION
6524 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006525
Arun Menon906de572013-06-18 17:01:40 -07006526 DESCRIPTION
6527 Checks if entire buffer pool is allocated by IL Client or not.
6528 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006529
Arun Menon906de572013-06-18 17:01:40 -07006530 PARAMETERS
6531 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006532
Arun Menon906de572013-06-18 17:01:40 -07006533 RETURN VALUE
6534 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006535
Arun Menon906de572013-06-18 17:01:40 -07006536 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006537bool omx_vdec::allocate_done(void)
6538{
Arun Menon906de572013-06-18 17:01:40 -07006539 bool bRet = false;
6540 bool bRet_In = false;
6541 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006542
Arun Menon906de572013-06-18 17:01:40 -07006543 bRet_In = allocate_input_done();
6544 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006545
Arun Menon906de572013-06-18 17:01:40 -07006546 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006547 bRet = true;
6548 }
Arun Menon906de572013-06-18 17:01:40 -07006549
6550 return bRet;
6551}
6552/* ======================================================================
6553 FUNCTION
6554 omx_vdec::AllocateInputDone
6555
6556 DESCRIPTION
6557 Checks if I/P buffer pool is allocated by IL Client or not.
6558
6559 PARAMETERS
6560 None.
6561
6562 RETURN VALUE
6563 true/false.
6564
6565 ========================================================================== */
6566bool omx_vdec::allocate_input_done(void)
6567{
6568 bool bRet = false;
6569 unsigned i=0;
6570
6571 if (m_inp_mem_ptr == NULL) {
6572 return bRet;
6573 }
6574 if (m_inp_mem_ptr ) {
6575 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6576 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6577 break;
6578 }
6579 }
6580 }
6581 if (i == drv_ctx.ip_buf.actualcount) {
6582 bRet = true;
6583 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6584 }
6585 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6586 m_inp_bPopulated = OMX_TRUE;
6587 }
6588 return bRet;
6589}
6590/* ======================================================================
6591 FUNCTION
6592 omx_vdec::AllocateOutputDone
6593
6594 DESCRIPTION
6595 Checks if entire O/P buffer pool is allocated by IL Client or not.
6596
6597 PARAMETERS
6598 None.
6599
6600 RETURN VALUE
6601 true/false.
6602
6603 ========================================================================== */
6604bool omx_vdec::allocate_output_done(void)
6605{
6606 bool bRet = false;
6607 unsigned j=0;
6608
6609 if (m_out_mem_ptr == NULL) {
6610 return bRet;
6611 }
6612
6613 if (m_out_mem_ptr) {
6614 for (; j < drv_ctx.op_buf.actualcount; j++) {
6615 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6616 break;
6617 }
6618 }
6619 }
6620
6621 if (j == drv_ctx.op_buf.actualcount) {
6622 bRet = true;
6623 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6624 if (m_out_bEnabled)
6625 m_out_bPopulated = OMX_TRUE;
6626 }
6627
6628 return bRet;
6629}
6630
6631/* ======================================================================
6632 FUNCTION
6633 omx_vdec::ReleaseDone
6634
6635 DESCRIPTION
6636 Checks if IL client has released all the buffers.
6637
6638 PARAMETERS
6639 None.
6640
6641 RETURN VALUE
6642 true/false
6643
6644 ========================================================================== */
6645bool omx_vdec::release_done(void)
6646{
6647 bool bRet = false;
6648
6649 if (release_input_done()) {
6650 if (release_output_done()) {
6651 bRet = true;
6652 }
6653 }
6654 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006655}
6656
6657
6658/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006659 FUNCTION
6660 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006661
Arun Menon906de572013-06-18 17:01:40 -07006662 DESCRIPTION
6663 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006664
Arun Menon906de572013-06-18 17:01:40 -07006665 PARAMETERS
6666 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006667
Arun Menon906de572013-06-18 17:01:40 -07006668 RETURN VALUE
6669 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006670
Arun Menon906de572013-06-18 17:01:40 -07006671 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006672bool omx_vdec::release_output_done(void)
6673{
Arun Menon906de572013-06-18 17:01:40 -07006674 bool bRet = false;
6675 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006676
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006677 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006678 if (m_out_mem_ptr) {
6679 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6680 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6681 break;
6682 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006683 }
Arun Menon906de572013-06-18 17:01:40 -07006684 if (j == drv_ctx.op_buf.actualcount) {
6685 m_out_bm_count = 0;
6686 bRet = true;
6687 }
6688 } else {
6689 m_out_bm_count = 0;
6690 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006691 }
Arun Menon906de572013-06-18 17:01:40 -07006692 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006693}
6694/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006695 FUNCTION
6696 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006697
Arun Menon906de572013-06-18 17:01:40 -07006698 DESCRIPTION
6699 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006700
Arun Menon906de572013-06-18 17:01:40 -07006701 PARAMETERS
6702 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006703
Arun Menon906de572013-06-18 17:01:40 -07006704 RETURN VALUE
6705 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006706
Arun Menon906de572013-06-18 17:01:40 -07006707 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006708bool omx_vdec::release_input_done(void)
6709{
Arun Menon906de572013-06-18 17:01:40 -07006710 bool bRet = false;
6711 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006712
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006713 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006714 if (m_inp_mem_ptr) {
6715 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6716 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6717 break;
6718 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006719 }
Arun Menon906de572013-06-18 17:01:40 -07006720 if (j==drv_ctx.ip_buf.actualcount) {
6721 bRet = true;
6722 }
6723 } else {
6724 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006725 }
Arun Menon906de572013-06-18 17:01:40 -07006726 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006727}
6728
6729OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006730 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006731{
Arun Menon906de572013-06-18 17:01:40 -07006732 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306733 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006734 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006735 return OMX_ErrorBadParameter;
6736 } else if (output_flush_progress) {
6737 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6738 buffer->nFilledLen = 0;
6739 buffer->nTimeStamp = 0;
6740 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6741 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6742 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006743 }
6744
Arun Menon906de572013-06-18 17:01:40 -07006745 if (m_debug_extradata) {
6746 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006747 DEBUG_PRINT_HIGH("");
6748 DEBUG_PRINT_HIGH("***************************************************");
6749 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6750 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006751 }
6752
6753 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006754 DEBUG_PRINT_HIGH("");
6755 DEBUG_PRINT_HIGH("***************************************************");
6756 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6757 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006758 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006759 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006760
6761
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006762 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006763 buffer, buffer->pBuffer);
6764 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006765
Arun Menon906de572013-06-18 17:01:40 -07006766 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006767 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006768 if (!output_flush_progress)
6769 post_event((unsigned)NULL, (unsigned)NULL,
6770 OMX_COMPONENT_GENERATE_EOS_DONE);
6771
6772 if (psource_frame) {
6773 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6774 psource_frame = NULL;
6775 }
6776 if (pdest_frame) {
6777 pdest_frame->nFilledLen = 0;
6778 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6779 (unsigned)NULL);
6780 pdest_frame = NULL;
6781 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006782 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006783
Shalaj Jain273b3e02012-06-22 19:08:03 -07006784
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006785 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6786 DEBUG_PRINT_LOW("Processing extradata");
6787 handle_extradata(buffer);
6788 }
6789
Arun Menon906de572013-06-18 17:01:40 -07006790 /* For use buffer we need to copy the data */
6791 if (!output_flush_progress) {
6792 /* This is the error check for non-recoverable errros */
6793 bool is_duplicate_ts_valid = true;
6794 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006795
Arun Menon906de572013-06-18 17:01:40 -07006796 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6797 output_capability == V4L2_PIX_FMT_MPEG2 ||
6798 output_capability == V4L2_PIX_FMT_DIVX ||
6799 output_capability == V4L2_PIX_FMT_DIVX_311)
6800 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006801
Arun Menon906de572013-06-18 17:01:40 -07006802 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
Arun Menon7b6fd642014-02-13 16:48:36 -08006803 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
Arun Menon906de572013-06-18 17:01:40 -07006804 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306805 }
Arun Menon906de572013-06-18 17:01:40 -07006806 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306807
Arun Menon906de572013-06-18 17:01:40 -07006808 if (buffer->nFilledLen > 0) {
6809 time_stamp_dts.get_next_timestamp(buffer,
6810 is_interlaced && is_duplicate_ts_valid);
6811 if (m_debug_timestamp) {
6812 {
6813 OMX_TICKS expected_ts = 0;
6814 m_timestamp_list.pop_min_ts(expected_ts);
6815 if (is_interlaced && is_duplicate_ts_valid) {
6816 m_timestamp_list.pop_min_ts(expected_ts);
6817 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006818 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006819 buffer->nTimeStamp, expected_ts);
6820
6821 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006822 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006823 }
6824 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306825 }
Arun Menon906de572013-06-18 17:01:40 -07006826 } else {
Arun Menon906de572013-06-18 17:01:40 -07006827 time_stamp_dts.remove_time_stamp(
6828 buffer->nTimeStamp,
6829 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306830 }
Arun Menon906de572013-06-18 17:01:40 -07006831
6832
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006833 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006834
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006835 /* Since we're passing around handles, adjust nFilledLen and nAllocLen
6836 * to size of the handle. Do it _after_ handle_extradata() which
6837 * requires the respective sizes to be accurate. */
6838 if (dynamic_buf_mode) {
6839 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
6840 buffer->nFilledLen = buffer->nFilledLen ?
6841 sizeof(struct VideoDecoderOutputMetaData) : 0;
6842 }
6843
Arun Menon906de572013-06-18 17:01:40 -07006844 if (m_cb.FillBufferDone) {
6845 if (buffer->nFilledLen > 0) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006846 if (arbitrary_bytes)
Arun Menon906de572013-06-18 17:01:40 -07006847 adjust_timestamp(buffer->nTimeStamp);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006848 else
6849 set_frame_rate(buffer->nTimeStamp);
6850
Arun Menon906de572013-06-18 17:01:40 -07006851 if (perf_flag) {
6852 if (!proc_frms) {
6853 dec_time.stop();
6854 latency = dec_time.processing_time_us() - latency;
6855 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6856 dec_time.start();
6857 fps_metrics.start();
6858 }
6859 proc_frms++;
6860 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6861 OMX_U64 proc_time = 0;
6862 fps_metrics.stop();
6863 proc_time = fps_metrics.processing_time_us();
6864 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006865 proc_frms, (float)proc_time / 1e6,
6866 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006867 proc_frms = 0;
6868 }
6869 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006870
6871#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006872 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006873
Arun Menon906de572013-06-18 17:01:40 -07006874 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6875 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6876 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6877 buffer->nFilledLen + 3)&(~3));
6878 while (p_extra &&
6879 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006880 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006881 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6882 if (p_extra->eType == OMX_ExtraDataNone) {
6883 break;
6884 }
6885 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6886 }
6887 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006888#endif
Arun Menon906de572013-06-18 17:01:40 -07006889 }
6890 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6891 prev_ts = LLONG_MAX;
6892 rst_prev_ts = true;
6893 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006894
Arun Menon906de572013-06-18 17:01:40 -07006895 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6896 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6897 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006898 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006899 OMX_BUFFERHEADERTYPE *il_buffer;
6900 il_buffer = client_buffers.get_il_buf_hdr(buffer);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006901
vivek mehta79cff222014-01-22 12:17:07 -08006902 if (il_buffer && m_last_rendered_TS >= 0) {
6903 int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
Manikanta Kanamarlapudifb53b262014-01-20 16:12:47 +05306904 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
vivek mehta79cff222014-01-22 12:17:07 -08006905
6906 // Current frame can be send for rendering if
6907 // (a) current FPS is <= 60
6908 // (b) is the next frame after the frame with TS 0
6909 // (c) is the first frame after seek
6910 // (d) the delta TS b\w two consecutive frames is > 16 ms
6911 // (e) its TS is equal to previous frame TS
6912 // (f) if marked EOS
6913
6914 if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
6915 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
6916 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006917 m_last_rendered_TS = il_buffer->nTimeStamp;
vivek mehta79cff222014-01-22 12:17:07 -08006918 } else {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006919 //mark for droping
vivek mehtaa75c69f2014-01-10 21:50:37 -08006920 buffer->nFilledLen = 0;
vivek mehta79cff222014-01-22 12:17:07 -08006921 }
6922
6923 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%d)",
6924 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
6925 il_buffer->nTimeStamp,ts_delta);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006926 }
6927
vivek mehta79cff222014-01-22 12:17:07 -08006928 if (il_buffer) {
Arun Menon9230eb82014-02-11 19:19:02 -08006929 log_output_buffers(il_buffer);
6930 if (dynamic_buf_mode) {
6931 unsigned int nPortIndex = 0;
6932 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6933
6934 if (!secure_mode) {
6935 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6936 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6937 }
6938
6939 //Clear graphic buffer handles in dynamic mode
6940 native_buffer[nPortIndex].privatehandle = NULL;
6941 native_buffer[nPortIndex].nativehandle = NULL;
6942 }
Arun Menon906de572013-06-18 17:01:40 -07006943 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
vivek mehta79cff222014-01-22 12:17:07 -08006944 } else {
Arun Menon906de572013-06-18 17:01:40 -07006945 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6946 return OMX_ErrorBadParameter;
6947 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006948 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006949 } else {
6950 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006951 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006952
Praveen Chavancf924182013-12-06 23:16:23 -08006953#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306954 if (m_smoothstreaming_mode && m_out_mem_ptr) {
Praveen Chavancf924182013-12-06 23:16:23 -08006955 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6956 BufferDim_t dim;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306957 private_handle_t *private_handle = NULL;
Pushkaraj Patil065b5732014-11-26 11:08:02 +05306958 dim.sliceWidth = framesize.nWidth;
6959 dim.sliceHeight = framesize.nHeight;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306960 if (native_buffer[buf_index].privatehandle)
6961 private_handle = native_buffer[buf_index].privatehandle;
Praveen Chavancf924182013-12-06 23:16:23 -08006962 if (private_handle) {
6963 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6964 dim.sliceWidth, dim.sliceHeight);
6965 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6966 }
6967 }
6968#endif
6969
Arun Menon906de572013-06-18 17:01:40 -07006970 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006971}
6972
6973OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006974 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006975{
6976
Surajit Podderd2644d52013-08-28 17:59:06 +05306977 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006978 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006979 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006980 }
6981
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006982 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006983 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006984 pending_input_buffers--;
6985
Arun Menon906de572013-06-18 17:01:40 -07006986 if (arbitrary_bytes) {
6987 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006988 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006989 pdest_frame = buffer;
6990 buffer->nFilledLen = 0;
6991 buffer->nTimeStamp = LLONG_MAX;
6992 push_input_buffer (hComp);
6993 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006994 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006995 buffer->nFilledLen = 0;
6996 if (!m_input_free_q.insert_entry((unsigned)buffer,
6997 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006998 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006999 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007000 }
Arun Menon906de572013-06-18 17:01:40 -07007001 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007002 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007003 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007004 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
7005 }
7006 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
7007 }
7008 return OMX_ErrorNone;
7009}
7010
Shalaj Jain273b3e02012-06-22 19:08:03 -07007011int omx_vdec::async_message_process (void *context, void* message)
7012{
Arun Menon906de572013-06-18 17:01:40 -07007013 omx_vdec* omx = NULL;
7014 struct vdec_msginfo *vdec_msg = NULL;
7015 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
7016 struct v4l2_buffer *v4l2_buf_ptr = NULL;
7017 struct vdec_output_frameinfo *output_respbuf = NULL;
7018 int rc=1;
7019 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007020 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07007021 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007022 }
Arun Menon906de572013-06-18 17:01:40 -07007023 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007024
Arun Menon906de572013-06-18 17:01:40 -07007025 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07007026
Arun Menon906de572013-06-18 17:01:40 -07007027 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007028
Arun Menon906de572013-06-18 17:01:40 -07007029 case VDEC_MSG_EVT_HW_ERROR:
7030 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7031 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7032 break;
7033
Deepak Verma24720fb2014-01-29 16:57:40 +05307034 case VDEC_MSG_EVT_HW_OVERLOAD:
7035 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7036 OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
7037 break;
7038
Arun Menon906de572013-06-18 17:01:40 -07007039 case VDEC_MSG_RESP_START_DONE:
7040 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7041 OMX_COMPONENT_GENERATE_START_DONE);
7042 break;
7043
7044 case VDEC_MSG_RESP_STOP_DONE:
7045 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7046 OMX_COMPONENT_GENERATE_STOP_DONE);
7047 break;
7048
7049 case VDEC_MSG_RESP_RESUME_DONE:
7050 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7051 OMX_COMPONENT_GENERATE_RESUME_DONE);
7052 break;
7053
7054 case VDEC_MSG_RESP_PAUSE_DONE:
7055 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7056 OMX_COMPONENT_GENERATE_PAUSE_DONE);
7057 break;
7058
7059 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
7060 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7061 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
7062 break;
7063 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
7064 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7065 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
7066 break;
7067 case VDEC_MSG_RESP_INPUT_FLUSHED:
7068 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
7069
7070 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
7071 vdec_msg->msgdata.input_frame_clientdata; */
7072
7073 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
7074 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
7075 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05307076 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07007077 omxhdr = NULL;
7078 vdec_msg->status_code = VDEC_S_EFATAL;
7079 }
7080 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
7081 DEBUG_PRINT_HIGH("Unsupported input");
7082 omx->omx_report_error ();
7083 }
7084 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
7085 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
7086 }
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307087 if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307088
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05307089 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
7090 android_atomic_dec(&omx->m_queued_codec_config_count);
7091 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
7092 BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
7093 DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307094 sem_post(&omx->m_safe_flush);
7095 }
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307096 }
7097
Arun Menon906de572013-06-18 17:01:40 -07007098 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
7099 OMX_COMPONENT_GENERATE_EBD);
7100 break;
7101 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
7102 int64_t *timestamp;
7103 timestamp = (int64_t *) malloc(sizeof(int64_t));
7104 if (timestamp) {
7105 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
7106 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
7107 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007108 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07007109 vdec_msg->msgdata.output_frame.time_stamp);
7110 }
7111 break;
7112 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
7113 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
7114
7115 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
7116 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307117
7118 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 -07007119 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307120 vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
7121 (unsigned int)vdec_msg->msgdata.output_frame.len,
7122 vdec_msg->msgdata.output_frame.framesize.left,
7123 vdec_msg->msgdata.output_frame.framesize.top,
7124 vdec_msg->msgdata.output_frame.framesize.right,
7125 vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07007126
7127 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05307128 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07007129 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05307130 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307131
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07007132 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
Arun Menon906de572013-06-18 17:01:40 -07007133 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
7134 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
7135 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
7136 omxhdr->nFlags = 0;
7137
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07007138 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07007139 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
7140 //rc = -1;
7141 }
7142 if (omxhdr->nFilledLen) {
7143 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
7144 }
7145 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
7146 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
7147 } else {
7148 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
7149 }
7150 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
7151 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7152 }
7153 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
7154 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
7155 }
Arun Menon7b6fd642014-02-13 16:48:36 -08007156
7157 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
7158 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
7159 }
7160
Arun Menonbdb80b02013-08-12 17:45:54 -07007161 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07007162 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07007163 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
7164 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
7165 }
Arun Menonbdb80b02013-08-12 17:45:54 -07007166 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
7167 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
7168 omxhdr->nOffset);
7169 }
Arun Menon906de572013-06-18 17:01:40 -07007170 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
7171 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07007172 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07007173 omx->time_stamp_dts.remove_time_stamp(
7174 omxhdr->nTimeStamp,
7175 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
7176 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07007177 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
7178 OMX_COMPONENT_GENERATE_FTB);
7179 break;
7180 }
7181 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
7182 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7183 }
7184 vdec_msg->msgdata.output_frame.bufferaddr =
7185 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307186
7187 /* Post event if resolution OR crop changed */
7188 /* filled length will be changed if resolution changed */
7189 /* Crop parameters can be changed even without resolution change */
7190 if (omxhdr->nFilledLen
7191 && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
7192 || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
7193 || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
7194 || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05307195 || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
7196 || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
7197 || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307198
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05307199 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",
7200 omx->prev_n_filled_len,
7201 omx->drv_ctx.video_resolution.frame_width,
7202 omx->drv_ctx.video_resolution.frame_height,
7203 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
7204 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
7205 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
7206 vdec_msg->msgdata.output_frame.picsize.frame_height,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307207 vdec_msg->msgdata.output_frame.framesize.left,
7208 vdec_msg->msgdata.output_frame.framesize.top,
7209 vdec_msg->msgdata.output_frame.framesize.right,
7210 vdec_msg->msgdata.output_frame.framesize.bottom);
7211
Maheshwar Ajja0f840ce2014-09-29 16:53:42 +05307212 omx->drv_ctx.video_resolution.frame_width =
7213 vdec_msg->msgdata.output_frame.picsize.frame_width;
7214 omx->drv_ctx.video_resolution.frame_height =
7215 vdec_msg->msgdata.output_frame.picsize.frame_height;
Praneeth Paladuguca80be72014-10-22 23:48:54 -07007216 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
7217 omx->drv_ctx.video_resolution.stride =
7218 VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
7219 omx->drv_ctx.video_resolution.scan_lines =
7220 VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
7221 }
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307222 memcpy(&omx->drv_ctx.frame_size,
7223 &vdec_msg->msgdata.output_frame.framesize,
7224 sizeof(struct vdec_framesize));
7225
7226 omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
7227 OMX_IndexConfigCommonOutputCrop,
7228 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Arun Menon906de572013-06-18 17:01:40 -07007229 }
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307230
Arun Menon906de572013-06-18 17:01:40 -07007231 if (omxhdr->nFilledLen)
7232 omx->prev_n_filled_len = omxhdr->nFilledLen;
7233
7234 output_respbuf = (struct vdec_output_frameinfo *)\
7235 omxhdr->pOutputPortPrivate;
7236 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7237 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307238
Arun Menon906de572013-06-18 17:01:40 -07007239 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
7240 output_respbuf->pic_type = PICTURE_TYPE_I;
7241 }
7242 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
7243 output_respbuf->pic_type = PICTURE_TYPE_P;
7244 }
7245 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7246 output_respbuf->pic_type = PICTURE_TYPE_B;
7247 }
7248
7249 if (omx->output_use_buffer)
7250 memcpy ( omxhdr->pBuffer, (void *)
7251 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7252 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7253 vdec_msg->msgdata.output_frame.len);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307254 } else {
7255 DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
7256 (unsigned int)vdec_msg->msgdata.output_frame.len,
7257 omxhdr->nAllocLen, omx->prev_n_filled_len);
Arun Menon906de572013-06-18 17:01:40 -07007258 omxhdr->nFilledLen = 0;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307259 }
7260
Arun Menon906de572013-06-18 17:01:40 -07007261 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7262 OMX_COMPONENT_GENERATE_FBD);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307263
7264 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07007265 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7266 OMX_COMPONENT_GENERATE_EOS_DONE);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307267 } else {
Arun Menon906de572013-06-18 17:01:40 -07007268 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7269 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307270 }
Arun Menon906de572013-06-18 17:01:40 -07007271 break;
7272 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007273 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07007274 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7275 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7276 break;
7277 default:
7278 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007279 }
Arun Menon906de572013-06-18 17:01:40 -07007280 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007281}
7282
7283OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07007284 OMX_HANDLETYPE hComp,
7285 OMX_BUFFERHEADERTYPE *buffer
7286 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07007287{
Arun Menon906de572013-06-18 17:01:40 -07007288 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007289 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007290
Arun Menon906de572013-06-18 17:01:40 -07007291 if (buffer == NULL) {
7292 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007293 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007294 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7295 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007296 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
7297
7298 /* return zero length and not an EOS buffer */
7299 /* return buffer if input flush in progress */
7300 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7301 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007302 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07007303 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7304 return OMX_ErrorNone;
7305 }
7306
7307 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007308 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007309 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007310 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07007311 push_input_buffer (hComp);
7312 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007313 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07007314 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7315 (unsigned)NULL)) {
7316 return OMX_ErrorBadParameter;
7317 }
7318 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007319
Sowmya Pandiri302f5ab2014-04-03 13:41:03 -07007320 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
7321 codec_config_flag = false;
7322 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007323
Arun Menon906de572013-06-18 17:01:40 -07007324 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007325}
7326
7327OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7328{
Arun Menon906de572013-06-18 17:01:40 -07007329 unsigned address,p2,id;
7330 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007331
Arun Menon906de572013-06-18 17:01:40 -07007332 if (pdest_frame == NULL || psource_frame == NULL) {
7333 /*Check if we have a destination buffer*/
7334 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007335 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007336 if (m_input_free_q.m_size) {
7337 m_input_free_q.pop_entry(&address,&p2,&id);
7338 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7339 pdest_frame->nFilledLen = 0;
7340 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007341 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007342 }
7343 }
7344
7345 /*Check if we have a destination buffer*/
7346 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007347 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007348 if (m_input_pending_q.m_size) {
7349 m_input_pending_q.pop_entry(&address,&p2,&id);
7350 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007351 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007352 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007353 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007354 psource_frame->nFlags,psource_frame->nFilledLen);
7355
7356 }
7357 }
7358
Shalaj Jain273b3e02012-06-22 19:08:03 -07007359 }
7360
Arun Menon906de572013-06-18 17:01:40 -07007361 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7362 switch (codec_type_parse) {
7363 case CODEC_TYPE_MPEG4:
7364 case CODEC_TYPE_H263:
7365 case CODEC_TYPE_MPEG2:
7366 ret = push_input_sc_codec(hComp);
7367 break;
7368 case CODEC_TYPE_H264:
7369 ret = push_input_h264(hComp);
7370 break;
7371 case CODEC_TYPE_VC1:
7372 ret = push_input_vc1(hComp);
7373 break;
7374 default:
7375 break;
7376 }
7377 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007378 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007379 omx_report_error ();
7380 break;
7381 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007382 }
7383
Arun Menon906de572013-06-18 17:01:40 -07007384 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007385}
7386
7387OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7388{
Arun Menon906de572013-06-18 17:01:40 -07007389 OMX_U32 partial_frame = 1;
7390 OMX_BOOL generate_ebd = OMX_TRUE;
7391 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007392
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007393 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007394 psource_frame,psource_frame->nTimeStamp);
7395 if (m_frame_parser.parse_sc_frame(psource_frame,
7396 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007397 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007398 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007399 }
Arun Menon906de572013-06-18 17:01:40 -07007400
7401 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007402 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007403 pdest_frame->nFilledLen,psource_frame,frame_count);
7404
7405
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007406 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007407 /*First Parsed buffer will have only header Hence skip*/
7408 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007409 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007410
7411 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7412 codec_type_parse == CODEC_TYPE_DIVX) {
7413 mp4StreamType psBits;
7414 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7415 psBits.numBytes = pdest_frame->nFilledLen;
7416 mp4_headerparser.parseHeader(&psBits);
7417 }
7418
7419 frame_count++;
7420 } else {
7421 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7422 if (pdest_frame->nFilledLen) {
7423 /*Push the frame to the Decoder*/
7424 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7425 return OMX_ErrorBadParameter;
7426 }
7427 frame_count++;
7428 pdest_frame = NULL;
7429
7430 if (m_input_free_q.m_size) {
7431 m_input_free_q.pop_entry(&address,&p2,&id);
7432 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7433 pdest_frame->nFilledLen = 0;
7434 }
7435 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007436 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007437 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7438 (unsigned)NULL);
7439 pdest_frame = NULL;
7440 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007441 }
Arun Menon906de572013-06-18 17:01:40 -07007442 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007443 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007444 /*Check if Destination Buffer is full*/
7445 if (pdest_frame->nAllocLen ==
7446 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007447 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007448 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007449 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007450 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007451
Arun Menon906de572013-06-18 17:01:40 -07007452 if (psource_frame->nFilledLen == 0) {
7453 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7454 if (pdest_frame) {
7455 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007456 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007457 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007458 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007459 pdest_frame->nFilledLen,frame_count++);
7460 /*Push the frame to the Decoder*/
7461 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7462 return OMX_ErrorBadParameter;
7463 }
7464 frame_count++;
7465 pdest_frame = NULL;
7466 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007467 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007468 generate_ebd = OMX_FALSE;
7469 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007470 }
Arun Menon906de572013-06-18 17:01:40 -07007471 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007472 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007473 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7474 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007475
Arun Menon906de572013-06-18 17:01:40 -07007476 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007477 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007478 m_input_pending_q.pop_entry(&address,&p2,&id);
7479 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007480 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007481 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007482 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007483 psource_frame->nFlags,psource_frame->nFilledLen);
7484 }
7485 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007486 }
Arun Menon906de572013-06-18 17:01:40 -07007487 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007488}
7489
7490OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7491{
Arun Menon906de572013-06-18 17:01:40 -07007492 OMX_U32 partial_frame = 1;
7493 unsigned address = 0, p2 = 0, id = 0;
7494 OMX_BOOL isNewFrame = OMX_FALSE;
7495 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007496
Arun Menon906de572013-06-18 17:01:40 -07007497 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007498 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007499 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007500 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007501 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007502 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007503 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007504 if (h264_scratch.nFilledLen && look_ahead_nal) {
7505 look_ahead_nal = false;
7506 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7507 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007508 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7509 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7510 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007511 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007512 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007513 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007514 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007515 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007516 }
Arun Menon906de572013-06-18 17:01:40 -07007517 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007518
7519 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7520 in EOS flag getting associated with the destination
7521 */
7522 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7523 pdest_frame->nFilledLen) {
7524 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7525 generate_ebd = OMX_FALSE;
7526 }
7527
Arun Menon906de572013-06-18 17:01:40 -07007528 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007529 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007530 if (m_frame_parser.parse_sc_frame(psource_frame,
7531 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007532 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007533 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007534 }
Arun Menon906de572013-06-18 17:01:40 -07007535 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007536 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007537 if (m_frame_parser.parse_h264_nallength(psource_frame,
7538 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007539 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007540 return OMX_ErrorBadParameter;
7541 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007542 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007543
Arun Menon906de572013-06-18 17:01:40 -07007544 if (partial_frame == 0) {
7545 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007546 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007547 nal_count++;
7548 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7549 h264_scratch.nFlags = psource_frame->nFlags;
7550 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007551 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007552 if (h264_scratch.nFilledLen) {
7553 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7554 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007555#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007556 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7557 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7558 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7559 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7560 // If timeinfo is present frame info from SEI is already processed
7561 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7562 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007563#endif
Arun Menon906de572013-06-18 17:01:40 -07007564 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7565 nal_count++;
7566 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7567 pdest_frame->nTimeStamp = h264_last_au_ts;
7568 pdest_frame->nFlags = h264_last_au_flags;
7569#ifdef PANSCAN_HDLR
7570 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7571 h264_parser->update_panscan_data(h264_last_au_ts);
7572#endif
7573 }
7574 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7575 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7576 h264_last_au_ts = h264_scratch.nTimeStamp;
7577 h264_last_au_flags = h264_scratch.nFlags;
7578#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7579 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7580 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7581 if (!VALID_TS(h264_last_au_ts))
7582 h264_last_au_ts = ts_in_sei;
7583 }
7584#endif
7585 } else
7586 h264_last_au_ts = LLONG_MAX;
7587 }
7588
7589 if (!isNewFrame) {
7590 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7591 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007592 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007593 h264_scratch.nFilledLen);
7594 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7595 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7596 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7597 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7598 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7599 h264_scratch.nFilledLen = 0;
7600 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007601 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007602 return OMX_ErrorBadParameter;
7603 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007604 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007605 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007606 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007607 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007608 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007609 pdest_frame->nFilledLen,frame_count++);
7610
7611 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007612 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007613 look_ahead_nal = false;
7614 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7615 h264_scratch.nFilledLen) {
7616 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7617 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7618 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7619 h264_scratch.nFilledLen = 0;
7620 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007621 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007622 return OMX_ErrorBadParameter;
7623 }
7624 } else {
7625 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007626 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007627 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7628 }
7629 /*Push the frame to the Decoder*/
7630 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7631 return OMX_ErrorBadParameter;
7632 }
7633 //frame_count++;
7634 pdest_frame = NULL;
7635 if (m_input_free_q.m_size) {
7636 m_input_free_q.pop_entry(&address,&p2,&id);
7637 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007638 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007639 pdest_frame->nFilledLen = 0;
7640 pdest_frame->nFlags = 0;
7641 pdest_frame->nTimeStamp = LLONG_MAX;
7642 }
7643 }
7644 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007645 }
Arun Menon906de572013-06-18 17:01:40 -07007646 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007647 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007648 /*Check if Destination Buffer is full*/
7649 if (h264_scratch.nAllocLen ==
7650 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007651 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007652 return OMX_ErrorStreamCorrupt;
7653 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007654 }
Arun Menon906de572013-06-18 17:01:40 -07007655
7656 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007657 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007658
7659 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7660 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007661 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007662 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7663 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007664 if(pdest_frame->nFilledLen == 0) {
7665 /* No residual frame from before, send whatever
7666 * we have left */
7667 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7668 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7669 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7670 h264_scratch.nFilledLen = 0;
7671 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7672 } else {
7673 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7674 if(!isNewFrame) {
7675 /* Have a residual frame, but we know that the
7676 * AU in this frame is belonging to whatever
7677 * frame we had left over. So append it */
7678 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7679 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7680 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7681 h264_scratch.nFilledLen = 0;
Balamurugan Alagarsamyefde3832014-09-22 19:52:20 +05307682 if (h264_last_au_ts != LLONG_MAX)
7683 pdest_frame->nTimeStamp = h264_last_au_ts;
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007684 } else {
7685 /* Completely new frame, let's just push what
7686 * we have now. The resulting EBD would trigger
7687 * another push */
7688 generate_ebd = OMX_FALSE;
7689 pdest_frame->nTimeStamp = h264_last_au_ts;
7690 h264_last_au_ts = h264_scratch.nTimeStamp;
7691 }
7692 }
Arun Menon906de572013-06-18 17:01:40 -07007693 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007694 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007695 return OMX_ErrorBadParameter;
7696 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007697
7698 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7699 if(generate_ebd == OMX_TRUE) {
7700 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7701 }
Arun Menon906de572013-06-18 17:01:40 -07007702
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007703 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007704 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007705 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007706#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7707 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7708 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7709 if (!VALID_TS(pdest_frame->nTimeStamp))
7710 pdest_frame->nTimeStamp = ts_in_sei;
7711 }
7712#endif
7713 /*Push the frame to the Decoder*/
7714 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7715 return OMX_ErrorBadParameter;
7716 }
7717 frame_count++;
7718 pdest_frame = NULL;
7719 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007720 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007721 pdest_frame,h264_scratch.nFilledLen);
7722 generate_ebd = OMX_FALSE;
7723 }
7724 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007725 }
Arun Menon906de572013-06-18 17:01:40 -07007726 if (generate_ebd && !psource_frame->nFilledLen) {
7727 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7728 psource_frame = NULL;
7729 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007730 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007731 m_input_pending_q.pop_entry(&address,&p2,&id);
7732 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007733 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007734 psource_frame->nFlags,psource_frame->nFilledLen);
7735 }
7736 }
7737 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007738}
7739
7740OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7741{
7742 OMX_U8 *buf, *pdest;
7743 OMX_U32 partial_frame = 1;
7744 OMX_U32 buf_len, dest_len;
7745
Arun Menon906de572013-06-18 17:01:40 -07007746 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007747 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007748 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007749 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007750 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007751 buf = psource_frame->pBuffer;
7752 buf_len = psource_frame->nFilledLen;
7753
7754 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007755 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007756 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007757 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007758 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007759 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007760 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007761 return OMX_ErrorStreamCorrupt;
7762 }
Arun Menon906de572013-06-18 17:01:40 -07007763 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007764 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7765 pdest_frame->nOffset;
7766 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007767 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007768
Arun Menon906de572013-06-18 17:01:40 -07007769 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007770 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007771 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007772 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007773 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7774 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7775 }
7776 }
7777 }
7778
Arun Menon906de572013-06-18 17:01:40 -07007779 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007780 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007781 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007782 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007783 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007784 return OMX_ErrorBadParameter;
7785 }
Arun Menon906de572013-06-18 17:01:40 -07007786 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007787
7788 case VC1_SP_MP_RCV:
7789 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007790 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007791 return OMX_ErrorBadParameter;
7792 }
7793 return OMX_ErrorNone;
7794}
7795
David Ng38e2d232013-03-15 20:05:58 -07007796#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007797bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007798 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007799{
Arun Menon906de572013-06-18 17:01:40 -07007800 struct pmem_allocation allocation;
7801 allocation.size = buffer_size;
7802 allocation.align = clip2(alignment);
7803 if (allocation.align < 4096) {
7804 allocation.align = 4096;
7805 }
7806 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007807 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007808 allocation.align, allocation.size);
7809 return false;
7810 }
7811 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007812}
David Ng38e2d232013-03-15 20:05:58 -07007813#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007814#ifdef USE_ION
7815int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007816 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7817 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007818{
Arun Menon906de572013-06-18 17:01:40 -07007819 int fd = -EINVAL;
7820 int rc = -EINVAL;
7821 int ion_dev_flag;
7822 struct vdec_ion ion_buf_info;
7823 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007824 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007825 return -EINVAL;
7826 }
7827 ion_dev_flag = O_RDONLY;
7828 fd = open (MEM_DEVICE, ion_dev_flag);
7829 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007830 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007831 return fd;
7832 }
7833 alloc_data->flags = 0;
7834 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7835 alloc_data->flags |= ION_FLAG_CACHED;
7836 }
7837 alloc_data->len = buffer_size;
7838 alloc_data->align = clip2(alignment);
7839 if (alloc_data->align < 4096) {
7840 alloc_data->align = 4096;
7841 }
7842 if ((secure_mode) && (flag & ION_SECURE))
7843 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007844
Arun Menon906de572013-06-18 17:01:40 -07007845 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307846 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007847 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7848 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7849 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007850 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007851 alloc_data->handle = NULL;
7852 close(fd);
7853 fd = -ENOMEM;
7854 return fd;
7855 }
7856 fd_data->handle = alloc_data->handle;
7857 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7858 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007859 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007860 ion_buf_info.ion_alloc_data = *alloc_data;
7861 ion_buf_info.ion_device_fd = fd;
7862 ion_buf_info.fd_ion_data = *fd_data;
7863 free_ion_memory(&ion_buf_info);
7864 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007865 fd = -ENOMEM;
7866 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007867
Arun Menon906de572013-06-18 17:01:40 -07007868 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007869}
7870
Arun Menon906de572013-06-18 17:01:40 -07007871void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7872{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007873
Arun Menon906de572013-06-18 17:01:40 -07007874 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007875 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007876 return;
7877 }
7878 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7879 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007880 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007881 }
7882 close(buf_ion_info->ion_device_fd);
7883 buf_ion_info->ion_device_fd = -1;
7884 buf_ion_info->ion_alloc_data.handle = NULL;
7885 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007886}
7887#endif
7888void omx_vdec::free_output_buffer_header()
7889{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007890 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007891 output_use_buffer = false;
7892 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007893
Arun Menon906de572013-06-18 17:01:40 -07007894 if (m_out_mem_ptr) {
7895 free (m_out_mem_ptr);
7896 m_out_mem_ptr = NULL;
7897 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007898
Arun Menon906de572013-06-18 17:01:40 -07007899 if (m_platform_list) {
7900 free(m_platform_list);
7901 m_platform_list = NULL;
7902 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007903
Arun Menon906de572013-06-18 17:01:40 -07007904 if (drv_ctx.ptr_respbuffer) {
7905 free (drv_ctx.ptr_respbuffer);
7906 drv_ctx.ptr_respbuffer = NULL;
7907 }
7908 if (drv_ctx.ptr_outputbuffer) {
7909 free (drv_ctx.ptr_outputbuffer);
7910 drv_ctx.ptr_outputbuffer = NULL;
7911 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007912#ifdef USE_ION
7913 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007914 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007915 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007916 drv_ctx.op_buf_ion_info = NULL;
7917 }
7918#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007919 if (out_dynamic_list) {
7920 free(out_dynamic_list);
7921 out_dynamic_list = NULL;
7922 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007923}
7924
7925void omx_vdec::free_input_buffer_header()
7926{
7927 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007928 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007929 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007930 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007931 free (m_inp_heap_ptr);
7932 m_inp_heap_ptr = NULL;
7933 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007934
Arun Menon906de572013-06-18 17:01:40 -07007935 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007936 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007937 free (m_phdr_pmem_ptr);
7938 m_phdr_pmem_ptr = NULL;
7939 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007940 }
Arun Menon906de572013-06-18 17:01:40 -07007941 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007942 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007943 free (m_inp_mem_ptr);
7944 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007945 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007946 /* We just freed all the buffer headers, every thing in m_input_free_q,
7947 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007948 while (m_input_free_q.m_size) {
7949 unsigned address, p2, id;
7950 m_input_free_q.pop_entry(&address, &p2, &id);
7951 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007952 while (m_input_pending_q.m_size) {
7953 unsigned address, p2, id;
7954 m_input_pending_q.pop_entry(&address, &p2, &id);
7955 }
7956 pdest_frame = NULL;
7957 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007958 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007959 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007960 free (drv_ctx.ptr_inputbuffer);
7961 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007962 }
7963#ifdef USE_ION
7964 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007965 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007966 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007967 drv_ctx.ip_buf_ion_info = NULL;
7968 }
7969#endif
7970}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007971
7972int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007973{
Arun Menon906de572013-06-18 17:01:40 -07007974 enum v4l2_buf_type btype;
7975 int rc = 0;
7976 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007977
Arun Menon906de572013-06-18 17:01:40 -07007978 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7979 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7980 v4l2_port = OUTPUT_PORT;
7981 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7982 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7983 v4l2_port = CAPTURE_PORT;
7984 } else if (port == OMX_ALL) {
7985 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7986 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007987
Arun Menon906de572013-06-18 17:01:40 -07007988 if (!rc_input)
7989 return rc_input;
7990 else
7991 return rc_output;
7992 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007993
Arun Menon906de572013-06-18 17:01:40 -07007994 if (!streaming[v4l2_port]) {
7995 // already streamed off, warn and move on
7996 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7997 " which is already streamed off", v4l2_port);
7998 return 0;
7999 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008000
Arun Menon906de572013-06-18 17:01:40 -07008001 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008002
Arun Menon906de572013-06-18 17:01:40 -07008003 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
8004 if (rc) {
8005 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008006 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07008007 } else {
8008 streaming[v4l2_port] = false;
8009 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008010
Arun Menon906de572013-06-18 17:01:40 -07008011 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008012}
8013
8014OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
8015{
Arun Menon906de572013-06-18 17:01:40 -07008016 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8017 struct v4l2_requestbuffers bufreq;
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07008018 unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308019 unsigned int final_extra_data_size = 0;
Arun Menon906de572013-06-18 17:01:40 -07008020 struct v4l2_format fmt;
8021 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008022 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008023 buffer_prop->actualcount, buffer_prop->buffer_size);
8024 bufreq.memory = V4L2_MEMORY_USERPTR;
8025 bufreq.count = 1;
8026 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8027 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8028 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8029 fmt.fmt.pix_mp.pixelformat = output_capability;
8030 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8031 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8032 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8033 fmt.fmt.pix_mp.pixelformat = capture_capability;
8034 } else {
8035 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008036 }
Arun Menon906de572013-06-18 17:01:40 -07008037 if (eRet==OMX_ErrorNone) {
8038 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008039 }
Arun Menon906de572013-06-18 17:01:40 -07008040 if (ret) {
8041 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8042 /*TODO: How to handle this case */
8043 eRet = OMX_ErrorInsufficientResources;
8044 return eRet;
8045 } else {
8046 buffer_prop->actualcount = bufreq.count;
8047 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008048 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008049 }
Arun Menon906de572013-06-18 17:01:40 -07008050 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
8051 buffer_prop->actualcount, buffer_prop->buffer_size);
8052
8053 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8054 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
8055
8056 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8057
8058 update_resolution(fmt.fmt.pix_mp.width,
8059 fmt.fmt.pix_mp.height,
8060 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
8061 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
8062 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
8063 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008064 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07008065
8066 if (ret) {
8067 /*TODO: How to handle this case */
8068 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8069 eRet = OMX_ErrorInsufficientResources;
8070 } else {
8071 int extra_idx = 0;
8072
8073 eRet = is_video_session_supported();
8074 if (eRet)
8075 return eRet;
8076
8077 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
8078 buf_size = buffer_prop->buffer_size;
8079 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
8080 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
8081 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
8082 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008083 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07008084 return OMX_ErrorBadParameter;
8085 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008086
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07008087 default_extra_data_size = VENUS_EXTRADATA_SIZE(
8088 drv_ctx.video_resolution.frame_height,
8089 drv_ctx.video_resolution.frame_width);
8090 final_extra_data_size = extra_data_size > default_extra_data_size ?
8091 extra_data_size : default_extra_data_size;
8092
8093 final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
8094 (~(buffer_prop->alignment - 1));
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07008095
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308096 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07008097 drv_ctx.extradata_info.count = buffer_prop->actualcount;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308098 drv_ctx.extradata_info.buffer_size = final_extra_data_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308099 if (!secure_mode)
8100 buf_size += final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07008101 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8102 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
8103 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008104 if (extra_data_size)
8105 DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%d)",
8106 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
8107
Arun Menon906de572013-06-18 17:01:40 -07008108 if (in_reconfig) // BufReq will be set to driver when port is disabled
8109 buffer_prop->buffer_size = buf_size;
8110 else if (buf_size != buffer_prop->buffer_size) {
8111 buffer_prop->buffer_size = buf_size;
8112 eRet = set_buffer_req(buffer_prop);
8113 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008114 }
Arun Menon906de572013-06-18 17:01:40 -07008115 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
8116 buffer_prop->actualcount, buffer_prop->buffer_size);
8117 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008118}
8119
8120OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
8121{
Arun Menon906de572013-06-18 17:01:40 -07008122 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8123 unsigned buf_size = 0;
8124 struct v4l2_format fmt;
8125 struct v4l2_requestbuffers bufreq;
8126 int ret;
8127 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
8128 buffer_prop->actualcount, buffer_prop->buffer_size);
8129 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8130 if (buf_size != buffer_prop->buffer_size) {
8131 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
8132 buffer_prop->buffer_size, buf_size);
8133 eRet = OMX_ErrorBadParameter;
8134 } else {
8135 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8136 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008137
Arun Menon906de572013-06-18 17:01:40 -07008138 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8139 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8140 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07008141 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07008142 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8143 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8144 fmt.fmt.pix_mp.pixelformat = capture_capability;
8145 } else {
8146 eRet = OMX_ErrorBadParameter;
8147 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008148
Arun Menon906de572013-06-18 17:01:40 -07008149 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
8150 if (ret) {
8151 /*TODO: How to handle this case */
8152 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
8153 eRet = OMX_ErrorInsufficientResources;
8154 }
8155
8156 bufreq.memory = V4L2_MEMORY_USERPTR;
8157 bufreq.count = buffer_prop->actualcount;
8158 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8159 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8160 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8161 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8162 } else {
8163 eRet = OMX_ErrorBadParameter;
8164 }
8165
8166 if (eRet==OMX_ErrorNone) {
8167 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8168 }
8169
8170 if (ret) {
8171 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8172 /*TODO: How to handle this case */
8173 eRet = OMX_ErrorInsufficientResources;
8174 } else if (bufreq.count < buffer_prop->actualcount) {
8175 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8176 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8177 buffer_prop->actualcount, bufreq.count);
8178 eRet = OMX_ErrorInsufficientResources;
8179 } else {
8180 if (!client_buffers.update_buffer_req()) {
8181 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8182 eRet = OMX_ErrorInsufficientResources;
8183 }
8184 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008185 }
Arun Menon906de572013-06-18 17:01:40 -07008186 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008187}
8188
Shalaj Jain273b3e02012-06-22 19:08:03 -07008189OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8190{
Arun Menon906de572013-06-18 17:01:40 -07008191 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8192 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008193}
8194
8195OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8196{
Arun Menon906de572013-06-18 17:01:40 -07008197 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308198 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07008199 if (!portDefn) {
8200 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008201 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008202 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07008203 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8204 portDefn->nSize = sizeof(portDefn);
8205 portDefn->eDomain = OMX_PortDomainVideo;
8206 if (drv_ctx.frame_rate.fps_denominator > 0)
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08008207 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
8208 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
Arun Menon906de572013-06-18 17:01:40 -07008209 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008210 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07008211 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008212 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308213 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Arun Menon906de572013-06-18 17:01:40 -07008214 if (0 == portDefn->nPortIndex) {
8215 portDefn->eDir = OMX_DirInput;
8216 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8217 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8218 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8219 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8220 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8221 portDefn->bEnabled = m_inp_bEnabled;
8222 portDefn->bPopulated = m_inp_bPopulated;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308223
8224 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8225 fmt.fmt.pix_mp.pixelformat = output_capability;
Arun Menon906de572013-06-18 17:01:40 -07008226 } else if (1 == portDefn->nPortIndex) {
8227 unsigned int buf_size = 0;
8228 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008229 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07008230 return OMX_ErrorHardware;
8231 }
8232 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008233 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07008234 return OMX_ErrorHardware;
8235 }
8236 portDefn->nBufferSize = buf_size;
8237 portDefn->eDir = OMX_DirOutput;
8238 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8239 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
8240 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8241 portDefn->bEnabled = m_out_bEnabled;
8242 portDefn->bPopulated = m_out_bPopulated;
8243 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008244 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07008245 return OMX_ErrorHardware;
8246 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308247 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8248 fmt.fmt.pix_mp.pixelformat = capture_capability;
Arun Menon906de572013-06-18 17:01:40 -07008249 } else {
8250 portDefn->eDir = OMX_DirMax;
8251 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8252 (int)portDefn->nPortIndex);
8253 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008254 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308255 if (is_down_scalar_enabled) {
8256 int ret = 0;
8257 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8258 if (ret) {
8259 DEBUG_PRINT_ERROR("update_portdef : Error in getting port resolution");
8260 return OMX_ErrorHardware;
8261 } else {
8262 portDefn->format.video.nFrameWidth = fmt.fmt.pix_mp.width;
8263 portDefn->format.video.nFrameHeight = fmt.fmt.pix_mp.height;
8264 portDefn->format.video.nStride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
8265 portDefn->format.video.nSliceHeight = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
8266 }
8267 } else {
8268 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8269 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8270 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8271 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
8272 }
8273
Praveen Chavandb7776f2014-02-06 18:17:25 -08008274 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
8275 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308276 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
8277 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
8278 }
8279 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
8280 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
8281 portDefn->nPortIndex,
8282 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07008283 portDefn->format.video.nFrameHeight,
8284 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308285 portDefn->format.video.nSliceHeight,
8286 portDefn->format.video.eColorFormat,
8287 portDefn->nBufferSize,
8288 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008289
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308290 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008291}
8292
8293OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8294{
Arun Menon906de572013-06-18 17:01:40 -07008295 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8296 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8297 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008298
Arun Menon906de572013-06-18 17:01:40 -07008299 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008300 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07008301 int nBufHdrSize = 0;
8302 int nPlatformEntrySize = 0;
8303 int nPlatformListSize = 0;
8304 int nPMEMInfoSize = 0;
8305 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8306 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8307 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008308
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008309 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008310 drv_ctx.op_buf.actualcount);
8311 nBufHdrSize = drv_ctx.op_buf.actualcount *
8312 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008313
Arun Menon906de572013-06-18 17:01:40 -07008314 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8315 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8316 nPlatformListSize = drv_ctx.op_buf.actualcount *
8317 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8318 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8319 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008320
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008321 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07008322 sizeof(OMX_BUFFERHEADERTYPE),
8323 nPMEMInfoSize,
8324 nPlatformListSize);
Deva Ramasubramanianeb819322014-07-17 14:23:35 -07008325 DEBUG_PRINT_LOW("PE %d bmSize %"PRId64, nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07008326 m_out_bm_count);
8327 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8328 // Alloc mem for platform specific info
8329 char *pPtr=NULL;
8330 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8331 nPMEMInfoSize,1);
8332 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8333 calloc (sizeof(struct vdec_bufferpayload),
8334 drv_ctx.op_buf.actualcount);
8335 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8336 calloc (sizeof (struct vdec_output_frameinfo),
8337 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008338 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
8339 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
8340 return OMX_ErrorInsufficientResources;
8341 }
8342
Shalaj Jain273b3e02012-06-22 19:08:03 -07008343#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008344 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8345 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008346 if (!drv_ctx.op_buf_ion_info) {
8347 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
8348 return OMX_ErrorInsufficientResources;
8349 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008350#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07008351 if (dynamic_buf_mode) {
8352 out_dynamic_list = (struct dynamic_buf_list *) \
8353 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
8354 }
Arun Menon906de572013-06-18 17:01:40 -07008355 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8356 && drv_ctx.ptr_respbuffer) {
8357 bufHdr = m_out_mem_ptr;
8358 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8359 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8360 (((char *) m_platform_list) + nPlatformListSize);
8361 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8362 (((char *) m_platform_entry) + nPlatformEntrySize);
8363 pPlatformList = m_platform_list;
8364 pPlatformEntry = m_platform_entry;
8365 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008366
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008367 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008368
Arun Menon906de572013-06-18 17:01:40 -07008369 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008370 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07008371 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008372 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07008373 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
8374 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8375 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8376 // Set the values when we determine the right HxW param
8377 bufHdr->nAllocLen = 0;
8378 bufHdr->nFilledLen = 0;
8379 bufHdr->pAppPrivate = NULL;
8380 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8381 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8382 pPlatformEntry->entry = pPMEMInfo;
8383 // Initialize the Platform List
8384 pPlatformList->nEntries = 1;
8385 pPlatformList->entryList = pPlatformEntry;
8386 // Keep pBuffer NULL till vdec is opened
8387 bufHdr->pBuffer = NULL;
8388 pPMEMInfo->offset = 0;
8389 pPMEMInfo->pmem_fd = 0;
8390 bufHdr->pPlatformPrivate = pPlatformList;
8391 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008392#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008393 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008394#endif
Arun Menon906de572013-06-18 17:01:40 -07008395 /*Create a mapping between buffers*/
8396 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8397 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8398 &drv_ctx.ptr_outputbuffer[i];
8399 // Move the buffer and buffer header pointers
8400 bufHdr++;
8401 pPMEMInfo++;
8402 pPlatformEntry++;
8403 pPlatformList++;
8404 }
8405 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008406 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008407 m_out_mem_ptr, pPtr);
8408 if (m_out_mem_ptr) {
8409 free(m_out_mem_ptr);
8410 m_out_mem_ptr = NULL;
8411 }
8412 if (pPtr) {
8413 free(pPtr);
8414 pPtr = NULL;
8415 }
8416 if (drv_ctx.ptr_outputbuffer) {
8417 free(drv_ctx.ptr_outputbuffer);
8418 drv_ctx.ptr_outputbuffer = NULL;
8419 }
8420 if (drv_ctx.ptr_respbuffer) {
8421 free(drv_ctx.ptr_respbuffer);
8422 drv_ctx.ptr_respbuffer = NULL;
8423 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008424#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008425 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008426 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008427 free(drv_ctx.op_buf_ion_info);
8428 drv_ctx.op_buf_ion_info = NULL;
8429 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008430#endif
Arun Menon906de572013-06-18 17:01:40 -07008431 eRet = OMX_ErrorInsufficientResources;
8432 }
8433 } else {
8434 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008435 }
Arun Menon906de572013-06-18 17:01:40 -07008436 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008437}
8438
8439void omx_vdec::complete_pending_buffer_done_cbs()
8440{
Arun Menon906de572013-06-18 17:01:40 -07008441 unsigned p1;
8442 unsigned p2;
8443 unsigned ident;
8444 omx_cmd_queue tmp_q, pending_bd_q;
8445 pthread_mutex_lock(&m_lock);
8446 // pop all pending GENERATE FDB from ftb queue
8447 while (m_ftb_q.m_size) {
8448 m_ftb_q.pop_entry(&p1,&p2,&ident);
8449 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8450 pending_bd_q.insert_entry(p1,p2,ident);
8451 } else {
8452 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008453 }
Arun Menon906de572013-06-18 17:01:40 -07008454 }
8455 //return all non GENERATE FDB to ftb queue
8456 while (tmp_q.m_size) {
8457 tmp_q.pop_entry(&p1,&p2,&ident);
8458 m_ftb_q.insert_entry(p1,p2,ident);
8459 }
8460 // pop all pending GENERATE EDB from etb queue
8461 while (m_etb_q.m_size) {
8462 m_etb_q.pop_entry(&p1,&p2,&ident);
8463 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8464 pending_bd_q.insert_entry(p1,p2,ident);
8465 } else {
8466 tmp_q.insert_entry(p1,p2,ident);
8467 }
8468 }
8469 //return all non GENERATE FDB to etb queue
8470 while (tmp_q.m_size) {
8471 tmp_q.pop_entry(&p1,&p2,&ident);
8472 m_etb_q.insert_entry(p1,p2,ident);
8473 }
8474 pthread_mutex_unlock(&m_lock);
8475 // process all pending buffer dones
8476 while (pending_bd_q.m_size) {
8477 pending_bd_q.pop_entry(&p1,&p2,&ident);
8478 switch (ident) {
8479 case OMX_COMPONENT_GENERATE_EBD:
8480 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008481 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008482 omx_report_error ();
8483 }
8484 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008485
Arun Menon906de572013-06-18 17:01:40 -07008486 case OMX_COMPONENT_GENERATE_FBD:
8487 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008488 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008489 omx_report_error ();
8490 }
8491 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008492 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008493 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008494}
8495
8496void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8497{
Arun Menon906de572013-06-18 17:01:40 -07008498 OMX_U32 new_frame_interval = 0;
8499 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8500 && llabs(act_timestamp - prev_ts) > 2000) {
8501 new_frame_interval = client_set_fps ? frm_int :
8502 llabs(act_timestamp - prev_ts);
Arun Menond9e49f82014-04-23 18:50:26 -07008503 if (new_frame_interval != frm_int || frm_int == 0) {
Arun Menon906de572013-06-18 17:01:40 -07008504 frm_int = new_frame_interval;
8505 if (frm_int) {
8506 drv_ctx.frame_rate.fps_numerator = 1e6;
8507 drv_ctx.frame_rate.fps_denominator = frm_int;
8508 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8509 frm_int, drv_ctx.frame_rate.fps_numerator /
8510 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008511
Arun Menon906de572013-06-18 17:01:40 -07008512 /* We need to report the difference between this FBD and the previous FBD
8513 * back to the driver for clock scaling purposes. */
8514 struct v4l2_outputparm oparm;
8515 /*XXX: we're providing timing info as seconds per frame rather than frames
8516 * per second.*/
8517 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8518 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008519
Arun Menon906de572013-06-18 17:01:40 -07008520 struct v4l2_streamparm sparm;
8521 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8522 sparm.parm.output = oparm;
8523 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8524 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8525 performance might be affected");
8526 }
8527
8528 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008529 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008530 }
Arun Menon906de572013-06-18 17:01:40 -07008531 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008532}
8533
8534void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8535{
Arun Menon906de572013-06-18 17:01:40 -07008536 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8537 prev_ts = act_timestamp;
8538 rst_prev_ts = false;
8539 } else if (VALID_TS(prev_ts)) {
8540 bool codec_cond = (drv_ctx.timestamp_adjust)?
Deva Ramasubramanian5f3cff32014-12-04 17:13:01 -08008541 (!VALID_TS(act_timestamp) || act_timestamp < prev_ts || llabs(act_timestamp - prev_ts) <= 2000) :
8542 (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts);
Arun Menon906de572013-06-18 17:01:40 -07008543 if (frm_int > 0 && codec_cond) {
8544 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8545 act_timestamp = prev_ts + frm_int;
8546 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8547 prev_ts = act_timestamp;
Leena Winterrowdd139fdc2014-08-05 18:04:25 -07008548 } else {
8549 if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
8550 // ensure that timestamps can never step backwards when in display order
8551 act_timestamp = prev_ts;
8552 }
Arun Menon906de572013-06-18 17:01:40 -07008553 set_frame_rate(act_timestamp);
Leena Winterrowdd139fdc2014-08-05 18:04:25 -07008554 }
Arun Menon906de572013-06-18 17:01:40 -07008555 } else if (frm_int > 0) // In this case the frame rate was set along
8556 { // with the port definition, start ts with 0
8557 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8558 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008559 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008560}
8561
8562void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8563{
Arun Menon906de572013-06-18 17:01:40 -07008564 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8565 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308566 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008567 OMX_U32 frame_rate = 0;
8568 int consumed_len = 0;
8569 OMX_U32 num_MB_in_frame;
8570 OMX_U32 recovery_sei_flags = 1;
8571 int enable = 0;
Arun Menon7b6fd642014-02-13 16:48:36 -08008572
Arun Menon906de572013-06-18 17:01:40 -07008573 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008574 if (buf_index >= drv_ctx.extradata_info.count) {
8575 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8576 buf_index, drv_ctx.extradata_info.count);
8577 return;
8578 }
Arun Menon906de572013-06-18 17:01:40 -07008579 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8580 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8581 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308582
Arun Menon906de572013-06-18 17:01:40 -07008583 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308584 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008585 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008586 }
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308587
8588 if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
8589 DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
8590 p_extra = NULL;
8591 return;
8592 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308593 if (!secure_mode)
8594 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008595 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308596 else
8597 p_extra = m_other_extradata;
8598
Arun Menon906de572013-06-18 17:01:40 -07008599 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308600 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
8601 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
Arun Menon906de572013-06-18 17:01:40 -07008602 p_extra = NULL;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308603 return;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008604 }
Arun Menon906de572013-06-18 17:01:40 -07008605 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008606 if (data && p_extra) {
Arun Menon906de572013-06-18 17:01:40 -07008607 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8608 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308609 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008610 DEBUG_PRINT_LOW("Invalid extra data size");
8611 break;
8612 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308613 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008614 switch ((unsigned long)data->eType) {
8615 case EXTRADATA_INTERLACE_VIDEO:
8616 struct msm_vidc_interlace_payload *payload;
8617 payload = (struct msm_vidc_interlace_payload *)data->data;
Arun Menon7b6fd642014-02-13 16:48:36 -08008618 if (payload) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008619 enable = 1;
Arun Menon7b6fd642014-02-13 16:48:36 -08008620 switch (payload->format) {
8621 case INTERLACE_FRAME_PROGRESSIVE:
8622 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8623 enable = 0;
8624 break;
8625 case INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
8626 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8627 break;
8628 case INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
8629 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
8630 break;
8631 default:
8632 DEBUG_PRINT_LOW("default case - set interlace to topfield");
8633 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8634 }
Arun Menon906de572013-06-18 17:01:40 -07008635 }
8636 if (m_enable_android_native_buffers)
8637 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8638 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308639 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon7b6fd642014-02-13 16:48:36 -08008640 append_interlace_extradata(p_extra, payload->format,
8641 p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
Arun Menon906de572013-06-18 17:01:40 -07008642 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8643 }
8644 break;
8645 case EXTRADATA_FRAME_RATE:
8646 struct msm_vidc_framerate_payload *frame_rate_payload;
8647 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8648 frame_rate = frame_rate_payload->frame_rate;
8649 break;
8650 case EXTRADATA_TIMESTAMP:
8651 struct msm_vidc_ts_payload *time_stamp_payload;
8652 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308653 time_stamp = time_stamp_payload->timestamp_lo;
8654 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8655 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008656 break;
8657 case EXTRADATA_NUM_CONCEALED_MB:
8658 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8659 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8660 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8661 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8662 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8663 break;
8664 case EXTRADATA_INDEX:
8665 int *etype;
8666 etype = (int *)(data->data);
8667 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8668 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8669 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8670 if (aspect_ratio_payload) {
8671 ((struct vdec_output_frameinfo *)
8672 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8673 ((struct vdec_output_frameinfo *)
8674 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8675 }
8676 }
8677 break;
8678 case EXTRADATA_RECOVERY_POINT_SEI:
8679 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8680 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8681 recovery_sei_flags = recovery_sei_payload->flags;
8682 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8683 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008684 DEBUG_PRINT_HIGH("");
8685 DEBUG_PRINT_HIGH("***************************************************");
8686 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8687 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008688 }
8689 break;
8690 case EXTRADATA_PANSCAN_WINDOW:
8691 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8692 break;
8693 case EXTRADATA_MPEG2_SEQDISP:
8694 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8695 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8696 if (seqdisp_payload) {
8697 m_disp_hor_size = seqdisp_payload->disp_width;
8698 m_disp_vert_size = seqdisp_payload->disp_height;
8699 }
8700 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308701 case EXTRADATA_S3D_FRAME_PACKING:
8702 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8703 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308704 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308705 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8706 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8707 }
8708 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008709 case EXTRADATA_FRAME_QP:
8710 struct msm_vidc_frame_qp_payload *qp_payload;
8711 qp_payload = (struct msm_vidc_frame_qp_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308712 if (client_extradata & OMX_QP_EXTRADATA) {
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008713 append_qp_extradata(p_extra, qp_payload);
8714 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8715 }
8716 break;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008717 case EXTRADATA_FRAME_BITS_INFO:
8718 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
8719 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308720 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008721 append_bitsinfo_extradata(p_extra, bits_info_payload);
8722 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8723 }
8724 break;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008725 case EXTRADATA_STREAM_USERDATA:
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308726 if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008727 append_user_extradata(p_extra, data);
8728 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8729 }
8730 break;
Arun Menon906de572013-06-18 17:01:40 -07008731 default:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008732 DEBUG_PRINT_LOW("Unrecognized extradata");
Arun Menon906de572013-06-18 17:01:40 -07008733 goto unrecognized_extradata;
8734 }
8735 consumed_len += data->nSize;
8736 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8737 }
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308738 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008739 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8740 append_frame_info_extradata(p_extra,
8741 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308742 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008743 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008744 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008745 }
8746 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008747unrecognized_extradata:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008748 if (client_extradata && p_extra) {
8749 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Arun Menon906de572013-06-18 17:01:40 -07008750 append_terminator_extradata(p_extra);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008751 }
8752
Arun Menonfd723932014-05-30 17:56:31 -07008753 if (secure_mode && p_extradata && m_other_extradata) {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308754 struct vdec_output_frameinfo *ptr_extradatabuff = NULL;
8755 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
8756 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
8757 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
8758 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
8759 }
Arun Menon906de572013-06-18 17:01:40 -07008760 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008761}
8762
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008763OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008764 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008765{
Arun Menon906de572013-06-18 17:01:40 -07008766 OMX_ERRORTYPE ret = OMX_ErrorNone;
8767 struct v4l2_control control;
8768 if (m_state != OMX_StateLoaded) {
8769 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8770 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008771 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008772 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008773 client_extradata, requested_extradata, enable, is_internal);
8774
8775 if (!is_internal) {
8776 if (enable)
8777 client_extradata |= requested_extradata;
8778 else
8779 client_extradata = client_extradata & ~requested_extradata;
8780 }
8781
8782 if (enable) {
8783 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8784 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8785 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8786 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8787 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008788 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008789 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308790 }
8791 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008792 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8793 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8794 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008795 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008796 }
8797 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8798 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8799 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008800 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008801 }
8802 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8803 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
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 recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008806 }
8807 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8808 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8809 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008810 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008811 }
8812 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8813 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8814 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008815 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008816 }
8817 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8818 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8819 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8820 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008821 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008822 }
8823 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308824 }
8825 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008826 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8827 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8828 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008829 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008830 }
8831 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308832 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8833 if (output_capability == V4L2_PIX_FMT_H264) {
8834 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8835 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8836 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8837 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8838 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8839 }
8840 } else {
8841 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8842 }
8843 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008844 if (requested_extradata & OMX_QP_EXTRADATA) {
8845 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8846 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
8847 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8848 DEBUG_PRINT_HIGH("Failed to set QP extradata");
8849 }
8850 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008851 if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
8852 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8853 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
8854 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8855 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
8856 }
8857 }
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008858 if (requested_extradata & OMX_EXTNUSER_EXTRADATA) {
8859 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8860 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
8861 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8862 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
8863 }
8864 }
Arun Menon906de572013-06-18 17:01:40 -07008865 }
8866 ret = get_buffer_req(&drv_ctx.op_buf);
8867 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008868}
8869
8870OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8871{
Arun Menon906de572013-06-18 17:01:40 -07008872 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8873 OMX_U8 *data_ptr = extra->data, data = 0;
8874 while (byte_count < extra->nDataSize) {
8875 data = *data_ptr;
8876 while (data) {
8877 num_MB += (data&0x01);
8878 data >>= 1;
8879 }
8880 data_ptr++;
8881 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008882 }
Arun Menon906de572013-06-18 17:01:40 -07008883 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8884 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8885 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008886}
8887
8888void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8889{
Arun Menon906de572013-06-18 17:01:40 -07008890 if (!m_debug_extradata)
8891 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008892
8893 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308894 "============== Extra Data ==============\n"
8895 " Size: %lu\n"
8896 " Version: %lu\n"
8897 " PortIndex: %lu\n"
8898 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008899 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008900 extra->nSize, extra->nVersion.nVersion,
8901 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008902
Arun Menon906de572013-06-18 17:01:40 -07008903 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8904 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8905 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308906 "------ Interlace Format ------\n"
8907 " Size: %lu\n"
8908 " Version: %lu\n"
8909 " PortIndex: %lu\n"
8910 " Is Interlace Format: %d\n"
8911 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008912 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008913 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8914 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8915 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8916 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8917
8918 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308919 "-------- Frame Format --------\n"
8920 " Picture Type: %d\n"
8921 " Interlace Type: %d\n"
8922 " Pan Scan Total Frame Num: %lu\n"
8923 " Concealed Macro Blocks: %lu\n"
8924 " frame rate: %lu\n"
8925 " Time Stamp: %llu\n"
8926 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008927 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008928 fminfo->ePicType,
8929 fminfo->interlaceType,
8930 fminfo->panScan.numWindows,
8931 fminfo->nConcealedMacroblocks,
8932 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308933 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008934 fminfo->aspectRatio.aspectRatioX,
8935 fminfo->aspectRatio.aspectRatioY);
8936
8937 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8938 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008939 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308940 " Pan Scan Frame Num: %lu\n"
8941 " Rectangle x: %ld\n"
8942 " Rectangle y: %ld\n"
8943 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008944 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008945 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8946 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8947 }
8948
8949 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308950 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8951 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8952 DEBUG_PRINT_HIGH(
8953 "------------------ Framepack Format ----------\n"
8954 " id: %lu \n"
8955 " cancel_flag: %lu \n"
8956 " type: %lu \n"
8957 " quincunx_sampling_flagFormat: %lu \n"
8958 " content_interpretation_type: %lu \n"
8959 " content_interpretation_type: %lu \n"
8960 " spatial_flipping_flag: %lu \n"
8961 " frame0_flipped_flag: %lu \n"
8962 " field_views_flag: %lu \n"
8963 " current_frame_is_frame0_flag: %lu \n"
8964 " frame0_self_contained_flag: %lu \n"
8965 " frame1_self_contained_flag: %lu \n"
8966 " frame0_grid_position_x: %lu \n"
8967 " frame0_grid_position_y: %lu \n"
8968 " frame1_grid_position_x: %lu \n"
8969 " frame1_grid_position_y: %lu \n"
8970 " reserved_byte: %lu \n"
8971 " repetition_period: %lu \n"
8972 " extension_flag: %lu \n"
8973 "================== End of Framepack ===========",
8974 framepack->id,
8975 framepack->cancel_flag,
8976 framepack->type,
8977 framepack->quincunx_sampling_flag,
8978 framepack->content_interpretation_type,
8979 framepack->spatial_flipping_flag,
8980 framepack->frame0_flipped_flag,
8981 framepack->field_views_flag,
8982 framepack->current_frame_is_frame0_flag,
8983 framepack->frame0_self_contained_flag,
8984 framepack->frame1_self_contained_flag,
8985 framepack->frame0_grid_position_x,
8986 framepack->frame0_grid_position_y,
8987 framepack->frame1_grid_position_x,
8988 framepack->frame1_grid_position_y,
8989 framepack->reserved_byte,
8990 framepack->repetition_period,
8991 framepack->extension_flag);
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008992 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
8993 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8994 DEBUG_PRINT_HIGH(
8995 "---- QP (Frame quantization parameter) ----\n"
8996 " Frame QP: %lu \n"
8997 "================ End of QP ================\n",
8998 qp->nQP);
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008999 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
9000 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)extra->data;
9001 DEBUG_PRINT_HIGH(
9002 "--------- Input bits information --------\n"
9003 " Header bits: %lu \n"
9004 " Frame bits: %lu \n"
9005 "===== End of Input bits information =====\n",
9006 bits->header_bits, bits->frame_bits);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009007 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
9008 OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)extra->data;
9009 OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
9010 OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
9011 OMX_U32 i = 0;
9012 DEBUG_PRINT_HIGH(
9013 "-------------- Userdata -------------\n"
9014 " Stream userdata type: %d\n"
9015 " userdata size: %d\n"
9016 " STREAM_USERDATA:",
9017 userdata->type, userdata_size);
9018 for (i = 0; i < userdata_size; i+=4) {
9019 DEBUG_PRINT_HIGH(" %x %x %x %x",
9020 data_ptr[i], data_ptr[i+1],
9021 data_ptr[i+2], data_ptr[i+3]);
9022 }
9023 DEBUG_PRINT_HIGH(
9024 "=========== End of Userdata ===========");
Arun Menon906de572013-06-18 17:01:40 -07009025 } else if (extra->eType == OMX_ExtraDataNone) {
9026 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
9027 } else {
9028 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07009029 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009030}
9031
9032void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon7b6fd642014-02-13 16:48:36 -08009033 OMX_U32 interlaced_format_type, bool is_mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009034{
Arun Menon906de572013-06-18 17:01:40 -07009035 OMX_STREAMINTERLACEFORMAT *interlace_format;
Arun Menon7b6fd642014-02-13 16:48:36 -08009036
Arun Menon906de572013-06-18 17:01:40 -07009037 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
9038 return;
9039 }
9040 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
9041 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9042 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9043 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
9044 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9045 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
9046 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9047 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
9048 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
Arun Menon7b6fd642014-02-13 16:48:36 -08009049
9050 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
Arun Menon906de572013-06-18 17:01:40 -07009051 interlace_format->bInterlaceFormat = OMX_FALSE;
9052 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
9053 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08009054 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009055 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08009056 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009057 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08009058 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009059 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08009060 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009061 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07009062 } else {
9063 interlace_format->bInterlaceFormat = OMX_TRUE;
9064 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
9065 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
9066 }
9067 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009068}
9069
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009070void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07009071 struct vdec_aspectratioinfo *aspect_ratio_info,
9072 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009073{
Arun Menon906de572013-06-18 17:01:40 -07009074 m_extradata = frame_info;
9075 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
9076 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309077 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07009078 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009079}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009080
9081void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07009082 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309083 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009084 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009085{
Arun Menon906de572013-06-18 17:01:40 -07009086 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
9087 struct msm_vidc_panscan_window *panscan_window;
9088 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009089 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009090 }
Arun Menon906de572013-06-18 17:01:40 -07009091 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
9092 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9093 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9094 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
9095 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
9096 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
9097 switch (picture_type) {
9098 case PICTURE_TYPE_I:
9099 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
9100 break;
9101 case PICTURE_TYPE_P:
9102 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
9103 break;
9104 case PICTURE_TYPE_B:
9105 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
9106 break;
9107 default:
9108 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
9109 }
9110 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
9111 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
9112 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
9113 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
9114 else
9115 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
9116 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
9117 frame_info->nConcealedMacroblocks = num_conceal_mb;
9118 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309119 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07009120 frame_info->panScan.numWindows = 0;
9121 if (output_capability == V4L2_PIX_FMT_MPEG2) {
9122 if (m_disp_hor_size && m_disp_vert_size) {
9123 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
9124 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
Pushkaraj Patil5e6ebd92014-03-10 10:29:14 +05309125 } else {
9126 frame_info->displayAspectRatio.displayHorizontalSize = 0;
9127 frame_info->displayAspectRatio.displayVerticalSize = 0;
Arun Menon906de572013-06-18 17:01:40 -07009128 }
9129 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009130
Arun Menon906de572013-06-18 17:01:40 -07009131 if (panscan_payload) {
9132 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
9133 panscan_window = &panscan_payload->wnd[0];
9134 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
9135 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
9136 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
9137 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
9138 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
9139 panscan_window++;
9140 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009141 }
Arun Menon906de572013-06-18 17:01:40 -07009142 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
9143 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009144}
9145
9146void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9147{
Arun Menon906de572013-06-18 17:01:40 -07009148 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
9149 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
9150 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9151 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9152 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
9153 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
9154 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
9155 *portDefn = m_port_def;
9156 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009157 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07009158 portDefn->format.video.nFrameWidth,
9159 portDefn->format.video.nStride,
9160 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009161}
9162
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05309163void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9164 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
9165{
9166 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
9167 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
9168 DEBUG_PRINT_ERROR("frame packing size mismatch");
9169 return;
9170 }
9171 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
9172 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9173 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9174 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
9175 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9176 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
9177 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9178 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
9179 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9180 memcpy(&framepack->id, s3d_frame_packing_payload,
9181 sizeof(struct msm_vidc_s3d_frame_packing_payload));
9182 memcpy(&m_frame_pack_arrangement, framepack,
9183 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
9184 print_debug_extradata(extra);
9185}
9186
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08009187void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9188 struct msm_vidc_frame_qp_payload *qp_payload)
9189{
9190 OMX_QCOM_EXTRADATA_QP * qp = NULL;
9191 if (!qp_payload) {
9192 DEBUG_PRINT_ERROR("QP payload is NULL");
9193 return;
9194 }
9195 extra->nSize = OMX_QP_EXTRADATA_SIZE;
9196 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9197 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9198 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
9199 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
9200 qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
9201 qp->nQP = qp_payload->frame_qp;
9202 print_debug_extradata(extra);
9203}
9204
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08009205void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9206 struct msm_vidc_frame_bits_info_payload *bits_payload)
9207{
9208 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
9209 if (!bits_payload) {
9210 DEBUG_PRINT_ERROR("bits info payload is NULL");
9211 return;
9212 }
9213 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
9214 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9215 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9216 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
9217 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
9218 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)extra->data;
9219 bits->frame_bits = bits_payload->frame_bits;
9220 bits->header_bits = bits_payload->header_bits;
9221 print_debug_extradata(extra);
9222}
9223
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009224void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9225 OMX_OTHER_EXTRADATATYPE *p_user)
9226{
9227 int userdata_size = 0;
9228 struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
9229 userdata_payload =
9230 (struct msm_vidc_stream_userdata_payload *)p_user->data;
9231 userdata_size = p_user->nDataSize;
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07009232 extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + p_user->nSize;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009233 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9234 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9235 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
9236 extra->nDataSize = userdata_size;
9237 if (extra->data && p_user->data && extra->nDataSize)
9238 memcpy(extra->data, p_user->data, extra->nDataSize);
9239 print_debug_extradata(extra);
9240}
9241
Shalaj Jain273b3e02012-06-22 19:08:03 -07009242void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9243{
Arun Menon906de572013-06-18 17:01:40 -07009244 if (!client_extradata) {
9245 return;
9246 }
9247 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
9248 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9249 extra->eType = OMX_ExtraDataNone;
9250 extra->nDataSize = 0;
9251 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009252
Arun Menon906de572013-06-18 17:01:40 -07009253 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009254}
9255
9256OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
9257{
Arun Menon906de572013-06-18 17:01:40 -07009258 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9259 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009260 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07009261 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009262 }
Arun Menon906de572013-06-18 17:01:40 -07009263 if (m_desc_buffer_ptr == NULL) {
9264 m_desc_buffer_ptr = (desc_buffer_hdr*) \
9265 calloc( (sizeof(desc_buffer_hdr)),
9266 drv_ctx.ip_buf.actualcount);
9267 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009268 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009269 return OMX_ErrorInsufficientResources;
9270 }
9271 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009272
Arun Menon906de572013-06-18 17:01:40 -07009273 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
9274 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009275 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009276 return OMX_ErrorInsufficientResources;
9277 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009278
Arun Menon906de572013-06-18 17:01:40 -07009279 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009280}
9281
9282void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
9283{
Arun Menon906de572013-06-18 17:01:40 -07009284 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
9285 if (m_demux_entries < 8192) {
9286 m_demux_offsets[m_demux_entries++] = address_offset;
9287 }
9288 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009289}
9290
9291void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
9292{
Arun Menon906de572013-06-18 17:01:40 -07009293 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
9294 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
9295 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009296
Arun Menon906de572013-06-18 17:01:40 -07009297 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009298
Arun Menon906de572013-06-18 17:01:40 -07009299 while (index < bytes_to_parse) {
9300 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9301 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
9302 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9303 (buf[index+2] == 0x01)) ) {
9304 //Found start code, insert address offset
9305 insert_demux_addr_offset(index);
9306 if (buf[index+2] == 0x01) // 3 byte start code
9307 index += 3;
9308 else //4 byte start code
9309 index += 4;
9310 } else
9311 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009312 }
Arun Menon906de572013-06-18 17:01:40 -07009313 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
9314 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009315}
9316
9317OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
9318{
Arun Menon906de572013-06-18 17:01:40 -07009319 //fix this, handle 3 byte start code, vc1 terminator entry
9320 OMX_U8 *p_demux_data = NULL;
9321 OMX_U32 desc_data = 0;
9322 OMX_U32 start_addr = 0;
9323 OMX_U32 nal_size = 0;
9324 OMX_U32 suffix_byte = 0;
9325 OMX_U32 demux_index = 0;
9326 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009327
Arun Menon906de572013-06-18 17:01:40 -07009328 if (m_desc_buffer_ptr == NULL) {
9329 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
9330 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009331 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009332
Arun Menon906de572013-06-18 17:01:40 -07009333 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
9334 if (buffer_index > drv_ctx.ip_buf.actualcount) {
9335 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
9336 return OMX_ErrorBadParameter;
9337 }
9338
9339 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9340
9341 if ( ((OMX_U8*)p_demux_data == NULL) ||
9342 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
9343 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9344 return OMX_ErrorBadParameter;
9345 } else {
9346 for (; demux_index < m_demux_entries; demux_index++) {
9347 desc_data = 0;
9348 start_addr = m_demux_offsets[demux_index];
9349 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
9350 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9351 } else {
9352 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9353 }
9354 if (demux_index < (m_demux_entries - 1)) {
9355 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9356 } else {
9357 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9358 }
9359 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9360 (void *)start_addr,
9361 suffix_byte,
9362 nal_size,
9363 demux_index);
9364 desc_data = (start_addr >> 3) << 1;
9365 desc_data |= (start_addr & 7) << 21;
9366 desc_data |= suffix_byte << 24;
9367
9368 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9369 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9370 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9371 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9372
9373 p_demux_data += 16;
9374 }
9375 if (codec_type_parse == CODEC_TYPE_VC1) {
9376 DEBUG_PRINT_LOW("VC1 terminator entry");
9377 desc_data = 0;
9378 desc_data = 0x82 << 24;
9379 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9380 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9381 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9382 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9383 p_demux_data += 16;
9384 m_demux_entries++;
9385 }
9386 //Add zero word to indicate end of descriptors
9387 memset(p_demux_data, 0, sizeof(OMX_U32));
9388
9389 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
9390 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
9391 }
9392 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9393 m_demux_entries = 0;
9394 DEBUG_PRINT_LOW("Demux table complete!");
9395 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009396}
9397
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009398OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009399{
Arun Menon906de572013-06-18 17:01:40 -07009400 OMX_ERRORTYPE err = OMX_ErrorNone;
9401 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9402 if (iDivXDrmDecrypt) {
9403 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9404 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009405 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009406 delete iDivXDrmDecrypt;
9407 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07009408 }
9409 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009410 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07009411 err = OMX_ErrorUndefined;
9412 }
9413 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009414}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009415
Vinay Kaliada4f4422013-01-09 10:45:03 -08009416omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9417{
Arun Menon906de572013-06-18 17:01:40 -07009418 enabled = false;
9419 omx = NULL;
9420 init_members();
9421 ColorFormat = OMX_COLOR_FormatMax;
Praveen Chavandb7776f2014-02-06 18:17:25 -08009422 dest_format = YCbCr420P;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009423}
9424
9425void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9426{
Arun Menon906de572013-06-18 17:01:40 -07009427 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009428}
9429
Arun Menon906de572013-06-18 17:01:40 -07009430void omx_vdec::allocate_color_convert_buf::init_members()
9431{
9432 allocated_count = 0;
9433 buffer_size_req = 0;
9434 buffer_alignment_req = 0;
9435 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9436 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9437 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9438 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009439#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009440 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009441#endif
Arun Menon906de572013-06-18 17:01:40 -07009442 for (int i = 0; i < MAX_COUNT; i++)
9443 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009444}
9445
Arun Menon906de572013-06-18 17:01:40 -07009446omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9447{
9448 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08009449}
9450
9451bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9452{
Arun Menon906de572013-06-18 17:01:40 -07009453 bool status = true;
9454 unsigned int src_size = 0, destination_size = 0;
9455 OMX_COLOR_FORMATTYPE drv_color_format;
9456 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009457 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009458 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009459 }
Arun Menon906de572013-06-18 17:01:40 -07009460 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009461 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07009462 return status;
9463 }
9464 pthread_mutex_lock(&omx->c_lock);
9465 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9466 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009467 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07009468 status = false;
9469 goto fail_update_buf_req;
9470 }
9471 c2d.close();
9472 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9473 omx->drv_ctx.video_resolution.frame_width,
Praveen Chavandb7776f2014-02-06 18:17:25 -08009474 NV12_128m,dest_format);
Arun Menon906de572013-06-18 17:01:40 -07009475 if (status) {
9476 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9477 if (status)
9478 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9479 }
9480 if (status) {
9481 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9482 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009483 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07009484 "driver size %d destination size %d",
9485 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9486 status = false;
9487 c2d.close();
9488 buffer_size_req = 0;
9489 } else {
9490 buffer_size_req = destination_size;
9491 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9492 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9493 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9494 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9495 }
9496 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009497fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07009498 pthread_mutex_unlock(&omx->c_lock);
9499 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009500}
9501
9502bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07009503 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009504{
Arun Menon906de572013-06-18 17:01:40 -07009505 bool status = true;
9506 OMX_COLOR_FORMATTYPE drv_color_format;
9507 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009508 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009509 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009510 }
Arun Menon906de572013-06-18 17:01:40 -07009511 pthread_mutex_lock(&omx->c_lock);
9512 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9513 drv_color_format = (OMX_COLOR_FORMATTYPE)
9514 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9515 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009516 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07009517 status = false;
9518 }
9519 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009520 DEBUG_PRINT_LOW("Enabling C2D");
Praveen Chavandb7776f2014-02-06 18:17:25 -08009521 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
9522 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009523 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009524 status = false;
9525 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009526 ColorFormat = dest_color_format;
9527 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
9528 YCbCr420P : YCbCr420SP;
Arun Menon906de572013-06-18 17:01:40 -07009529 if (enabled)
9530 c2d.destroy();
9531 enabled = false;
9532 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009533 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009534 status = false;
9535 } else
9536 enabled = true;
9537 }
9538 } else {
9539 if (enabled)
9540 c2d.destroy();
9541 enabled = false;
9542 }
9543 pthread_mutex_unlock(&omx->c_lock);
9544 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009545}
9546
9547OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9548{
Arun Menon906de572013-06-18 17:01:40 -07009549 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009550 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009551 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009552 }
Arun Menon906de572013-06-18 17:01:40 -07009553 if (!enabled)
9554 return omx->m_out_mem_ptr;
9555 return m_out_mem_ptr_client;
9556}
9557
9558 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9559(OMX_BUFFERHEADERTYPE *bufadd)
9560{
9561 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009562 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009563 return NULL;
9564 }
9565 if (!enabled)
9566 return bufadd;
9567
9568 unsigned index = 0;
9569 index = bufadd - omx->m_out_mem_ptr;
9570 if (index < omx->drv_ctx.op_buf.actualcount) {
9571 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9572 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9573 bool status;
9574 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9575 pthread_mutex_lock(&omx->c_lock);
9576 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9577 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9578 pmem_baseaddress[index], pmem_baseaddress[index]);
Arun Menon906de572013-06-18 17:01:40 -07009579 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009580 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009581 m_out_mem_ptr_client[index].nFilledLen = 0;
Leena Winterrowd270a7042014-09-30 13:05:55 -07009582 pthread_mutex_unlock(&omx->c_lock);
Arun Menon906de572013-06-18 17:01:40 -07009583 return &m_out_mem_ptr_client[index];
Praveen Chavan6d6b7252014-09-15 17:05:54 -07009584 } else {
9585 unsigned int filledLen = 0;
9586 c2d.get_output_filled_length(filledLen);
9587 m_out_mem_ptr_client[index].nFilledLen = filledLen;
Arun Menon906de572013-06-18 17:01:40 -07009588 }
Leena Winterrowd270a7042014-09-30 13:05:55 -07009589 pthread_mutex_unlock(&omx->c_lock);
Arun Menon906de572013-06-18 17:01:40 -07009590 } else
9591 m_out_mem_ptr_client[index].nFilledLen = 0;
9592 return &m_out_mem_ptr_client[index];
9593 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009594 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009595 return NULL;
9596}
9597
9598 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9599(OMX_BUFFERHEADERTYPE *bufadd)
9600{
9601 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009602 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009603 return NULL;
9604 }
9605 if (!enabled)
9606 return bufadd;
9607 unsigned index = 0;
9608 index = bufadd - m_out_mem_ptr_client;
9609 if (index < omx->drv_ctx.op_buf.actualcount) {
9610 return &omx->m_out_mem_ptr[index];
9611 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009612 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009613 return NULL;
9614}
9615 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9616(unsigned int &buffer_size)
9617{
9618 bool status = true;
9619 pthread_mutex_lock(&omx->c_lock);
9620 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009621 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009622 else {
9623 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009624 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009625 status = false;
9626 goto fail_get_buffer_size;
9627 }
9628 }
9629 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9630 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9631 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9632 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009633fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009634 pthread_mutex_unlock(&omx->c_lock);
9635 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009636}
9637OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009638 OMX_BUFFERHEADERTYPE *bufhdr)
9639{
9640 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009641
Arun Menon906de572013-06-18 17:01:40 -07009642 if (!enabled)
9643 return omx->free_output_buffer(bufhdr);
9644 if (enabled && omx->is_component_secure())
9645 return OMX_ErrorNone;
9646 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009647 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009648 return OMX_ErrorBadParameter;
9649 }
9650 index = bufhdr - m_out_mem_ptr_client;
9651 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009652 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009653 return OMX_ErrorBadParameter;
9654 }
9655 if (pmem_fd[index] > 0) {
9656 munmap(pmem_baseaddress[index], buffer_size_req);
9657 close(pmem_fd[index]);
9658 }
9659 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009660#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009661 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009662#endif
Arun Menon906de572013-06-18 17:01:40 -07009663 m_heap_ptr[index].video_heap_ptr = NULL;
9664 if (allocated_count > 0)
9665 allocated_count--;
9666 else
9667 allocated_count = 0;
9668 if (!allocated_count) {
9669 pthread_mutex_lock(&omx->c_lock);
9670 c2d.close();
9671 init_members();
9672 pthread_mutex_unlock(&omx->c_lock);
9673 }
9674 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009675}
9676
9677OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009678 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009679{
Arun Menon906de572013-06-18 17:01:40 -07009680 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9681 if (!enabled) {
9682 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9683 return eRet;
9684 }
9685 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009686 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009687 omx->is_component_secure());
9688 return OMX_ErrorUnsupportedSetting;
9689 }
9690 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009691 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9692 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009693 buffer_size_req,bytes);
9694 return OMX_ErrorBadParameter;
9695 }
9696 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009697 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009698 return OMX_ErrorInsufficientResources;
9699 }
9700 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9701 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9702 port,appData,omx->drv_ctx.op_buf.buffer_size);
9703 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009704 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009705 return eRet;
9706 }
9707 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309708 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009709 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009710 (temp_bufferHdr - omx->m_out_mem_ptr));
9711 return OMX_ErrorUndefined;
9712 }
9713 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009714#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009715 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9716 buffer_size_req,buffer_alignment_req,
9717 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9718 0);
9719 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9720 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009721 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009722 return OMX_ErrorInsufficientResources;
9723 }
9724 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9725 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009726
Arun Menon906de572013-06-18 17:01:40 -07009727 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009728 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009729 close(pmem_fd[i]);
9730 omx->free_ion_memory(&op_buf_ion_info[i]);
9731 return OMX_ErrorInsufficientResources;
9732 }
9733 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9734 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9735 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009736#endif
Arun Menon906de572013-06-18 17:01:40 -07009737 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9738 m_pmem_info_client[i].offset = 0;
9739 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9740 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9741 m_platform_list_client[i].nEntries = 1;
9742 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9743 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9744 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9745 m_out_mem_ptr_client[i].nFilledLen = 0;
9746 m_out_mem_ptr_client[i].nFlags = 0;
9747 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9748 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9749 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9750 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9751 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9752 m_out_mem_ptr_client[i].pAppPrivate = appData;
9753 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009754 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009755 allocated_count++;
9756 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009757}
9758
9759bool omx_vdec::is_component_secure()
9760{
Arun Menon906de572013-06-18 17:01:40 -07009761 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009762}
9763
9764bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9765{
Arun Menon906de572013-06-18 17:01:40 -07009766 bool status = true;
9767 if (!enabled) {
9768 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9769 dest_color_format = (OMX_COLOR_FORMATTYPE)
9770 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9771 else
9772 status = false;
9773 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009774 if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
9775 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
9776 dest_color_format = ColorFormat;
Arun Menon906de572013-06-18 17:01:40 -07009777 } else
Praveen Chavandb7776f2014-02-06 18:17:25 -08009778 status = false;
Arun Menon906de572013-06-18 17:01:40 -07009779 }
9780 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009781}
Arun Menonbdb80b02013-08-12 17:45:54 -07009782
Arun Menonbdb80b02013-08-12 17:45:54 -07009783void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9784{
9785 int i = 0;
9786 bool buf_present = false;
9787 pthread_mutex_lock(&m_lock);
9788 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9789 //check the buffer fd, offset, uv addr with list contents
9790 //If present increment reference.
9791 if ((out_dynamic_list[i].fd == fd) &&
9792 (out_dynamic_list[i].offset == offset)) {
9793 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009794 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009795 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9796 buf_present = true;
9797 break;
9798 }
9799 }
9800 if (!buf_present) {
9801 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9802 //search for a entry to insert details of the new buffer
9803 if (out_dynamic_list[i].dup_fd == 0) {
9804 out_dynamic_list[i].fd = fd;
9805 out_dynamic_list[i].offset = offset;
9806 out_dynamic_list[i].dup_fd = dup(fd);
9807 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009808 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009809 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9810 break;
9811 }
9812 }
9813 }
9814 pthread_mutex_unlock(&m_lock);
9815}
9816
9817void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9818{
9819 int i = 0;
9820 pthread_mutex_lock(&m_lock);
9821 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9822 //check the buffer fd, offset, uv addr with list contents
9823 //If present decrement reference.
9824 if ((out_dynamic_list[i].fd == fd) &&
9825 (out_dynamic_list[i].offset == offset)) {
9826 out_dynamic_list[i].ref_count--;
9827 if (out_dynamic_list[i].ref_count == 0) {
9828 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009829 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009830 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9831 out_dynamic_list[i].dup_fd = 0;
9832 out_dynamic_list[i].fd = 0;
9833 out_dynamic_list[i].offset = 0;
9834 }
9835 break;
9836 }
9837 }
9838 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009839 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009840 }
9841 pthread_mutex_unlock(&m_lock);
9842}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009843
Arun Menon1fc764f2014-04-17 15:41:27 -07009844OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
9845 unsigned long nMaxFrameHeight)
9846{
9847
9848 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9849 int ret = 0;
9850 unsigned long min_res_buf_count = 0;
9851
9852 eRet = enable_smoothstreaming();
9853 if (eRet != OMX_ErrorNone) {
9854 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
9855 return eRet;
9856 }
9857
9858 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
9859 nMaxFrameWidth,
9860 nMaxFrameHeight);
9861 m_smoothstreaming_mode = true;
9862 m_smoothstreaming_width = nMaxFrameWidth;
9863 m_smoothstreaming_height = nMaxFrameHeight;
9864
9865 //Get upper limit buffer count for min supported resolution
9866 struct v4l2_format fmt;
9867 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9868 fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
9869 fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
9870 fmt.fmt.pix_mp.pixelformat = output_capability;
9871
9872 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9873 if (ret) {
9874 DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
9875 m_decoder_capability.min_height,
9876 m_decoder_capability.min_width);
9877 return OMX_ErrorUnsupportedSetting;
9878 }
9879
9880 eRet = get_buffer_req(&drv_ctx.op_buf);
9881 if (eRet != OMX_ErrorNone) {
9882 DEBUG_PRINT_ERROR("failed to get_buffer_req");
9883 return eRet;
9884 }
9885
9886 min_res_buf_count = drv_ctx.op_buf.mincount;
9887 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
9888 min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
9889
9890 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
9891 m_smoothstreaming_width, m_smoothstreaming_height);
9892 eRet = is_video_session_supported();
9893 if (eRet != OMX_ErrorNone) {
9894 DEBUG_PRINT_ERROR("video session is not supported");
9895 return eRet;
9896 }
9897
9898 //Get upper limit buffer size for max smooth streaming resolution set
9899 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9900 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
9901 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
9902 fmt.fmt.pix_mp.pixelformat = output_capability;
9903 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9904 if (ret) {
9905 DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
9906 return OMX_ErrorUnsupportedSetting;
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_LOW("enable adaptive - upper limit buffer size = %u",
9915 drv_ctx.op_buf.buffer_size);
9916
9917 drv_ctx.op_buf.mincount = min_res_buf_count;
9918 drv_ctx.op_buf.actualcount = min_res_buf_count;
9919 eRet = set_buffer_req(&drv_ctx.op_buf);
9920 if (eRet != OMX_ErrorNone) {
9921 DEBUG_PRINT_ERROR("failed to set_buffer_req");
9922 return eRet;
9923 }
9924
9925 eRet = get_buffer_req(&drv_ctx.op_buf);
9926 if (eRet != OMX_ErrorNone) {
9927 DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
9928 return eRet;
9929 }
9930 DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
9931 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size);
9932 return eRet;
9933}
9934
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009935#ifdef _MSM8974_
9936void omx_vdec::send_codec_config() {
9937 if (codec_config_flag) {
9938 unsigned p1 = 0; // Parameter - 1
9939 unsigned p2 = 0; // Parameter - 2
9940 unsigned ident = 0;
9941 pthread_mutex_lock(&m_lock);
9942 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9943 while (m_etb_q.m_size) {
9944 m_etb_q.pop_entry(&p1,&p2,&ident);
9945 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9946 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9947 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9948 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9949 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9950 omx_report_error();
9951 }
9952 } else {
9953 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9954 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9955 }
9956 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9957 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9958 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9959 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9960 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9961 omx_report_error ();
9962 }
9963 } else {
9964 pending_input_buffers++;
9965 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9966 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9967 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9968 }
9969 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9970 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9971 (OMX_BUFFERHEADERTYPE *)p1);
9972 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9973 }
9974 }
9975 pthread_mutex_unlock(&m_lock);
9976 }
9977}
9978#endif
Praveen Chavan09a82b72014-10-18 09:09:45 -07009979
9980//static
9981OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
9982
9983#ifndef FLEXYUV_SUPPORTED
9984 (void)pParam;
9985 return OMX_ErrorUndefined;
9986#else
9987
9988 if (pParam == NULL) {
9989 DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
9990 return OMX_ErrorBadParameter;
9991 }
9992
9993 DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
9994
9995 MediaImage *img = &(params->sMediaImage);
9996 switch(params->eColorFormat) {
9997 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
9998 {
9999 img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
10000 img->mNumPlanes = 3;
10001 // mWidth and mHeight represent the W x H of the largest plane
10002 // In our case, this happens to be the Stride x Scanlines of Y plane
10003 img->mWidth = params->nFrameWidth;
10004 img->mHeight = params->nFrameHeight;
10005 size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
10006 size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
10007 img->mBitDepth = 8;
10008 //Plane 0 (Y)
10009 img->mPlane[MediaImage::Y].mOffset = 0;
10010 img->mPlane[MediaImage::Y].mColInc = 1;
10011 img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
10012 img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
10013 img->mPlane[MediaImage::Y].mVertSubsampling = 1;
10014 //Plane 1 (U)
10015 img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
10016 img->mPlane[MediaImage::U].mColInc = 2; //interleaved UV
10017 img->mPlane[MediaImage::U].mRowInc =
10018 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
10019 img->mPlane[MediaImage::U].mHorizSubsampling = 2;
10020 img->mPlane[MediaImage::U].mVertSubsampling = 2;
10021 //Plane 2 (V)
10022 img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
10023 img->mPlane[MediaImage::V].mColInc = 2; //interleaved UV
10024 img->mPlane[MediaImage::V].mRowInc =
10025 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
10026 img->mPlane[MediaImage::V].mHorizSubsampling = 2;
10027 img->mPlane[MediaImage::V].mVertSubsampling = 2;
10028 break;
10029 }
10030
10031 case OMX_COLOR_FormatYUV420Planar:
10032 case OMX_COLOR_FormatYUV420SemiPlanar:
10033 // We need not describe the standard OMX linear formats as these are
10034 // understood by client. Fail this deliberately to let client fill-in
10035 return OMX_ErrorUnsupportedSetting;
10036
10037 default:
10038 // Rest all formats which are non-linear cannot be described
10039 DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
10040 img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
10041 return OMX_ErrorNone;
10042 };
10043
10044 DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
10045 DEBUG_PRINT_LOW(" FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
10046 DEBUG_PRINT_LOW(" YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
10047 for (size_t i = 0; i < img->mNumPlanes; ++i) {
10048 DEBUG_PRINT_LOW(" Plane[%d] : offset=%d / xStep=%d / yStep = %d",
10049 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
10050 }
10051 return OMX_ErrorNone;
10052#endif //FLEXYUV_SUPPORTED
10053}
10054