blob: dc26ab692fcccdb8d50d979545d8d31ab8357cc4 [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 Ramasubramanian286a3582014-08-25 18:09:38 -0700577 ignore_not_coded_vops(true),
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -0700578 m_last_rendered_TS(-1),
579 m_queued_codec_config_count(0)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700580{
Arun Menon906de572013-06-18 17:01:40 -0700581 /* Assumption is that , to begin with , we have all the frames with decoder */
582 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700583 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700584#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700585 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700586 property_get("vidc.debug.level", property_value, "0");
587 debug_level = atoi(property_value);
588 property_value[0] = '\0';
589
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700590 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
591
Arun Menon906de572013-06-18 17:01:40 -0700592 property_get("vidc.dec.debug.perf", property_value, "0");
593 perf_flag = atoi(property_value);
594 if (perf_flag) {
595 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
596 dec_time.start();
597 proc_frms = latency = 0;
598 }
599 prev_n_filled_len = 0;
600 property_value[0] = '\0';
601 property_get("vidc.dec.debug.ts", property_value, "0");
602 m_debug_timestamp = atoi(property_value);
603 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
604 if (m_debug_timestamp) {
605 time_stamp_dts.set_timestamp_reorder_mode(true);
606 time_stamp_dts.enable_debug_print(true);
607 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700608
Arun Menon906de572013-06-18 17:01:40 -0700609 property_value[0] = '\0';
610 property_get("vidc.dec.debug.concealedmb", property_value, "0");
611 m_debug_concealedmb = atoi(property_value);
612 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700613
Arun Menon906de572013-06-18 17:01:40 -0700614 property_value[0] = '\0';
615 property_get("vidc.dec.profile.check", property_value, "0");
616 m_reject_avc_1080p_mp = atoi(property_value);
617 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530618
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700619 property_value[0] = '\0';
620 property_get("vidc.dec.log.in", property_value, "0");
621 m_debug.in_buffer_log = atoi(property_value);
622
623 property_value[0] = '\0';
624 property_get("vidc.dec.log.out", property_value, "0");
625 m_debug.out_buffer_log = atoi(property_value);
626 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
627
628 property_value[0] = '\0';
629 property_get("vidc.log.loc", property_value, "");
630 if (*property_value)
631 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
vivek mehta79cff222014-01-22 12:17:07 -0800632
633 property_value[0] = '\0';
634 property_get("vidc.dec.120fps.enabled", property_value, "0");
635
636 //if this feature is not enabled then reset this value -ve
637 if(atoi(property_value)) {
638 DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
639 m_last_rendered_TS = 0;
640 }
641
Shalaj Jain273b3e02012-06-22 19:08:03 -0700642#endif
Arun Menon906de572013-06-18 17:01:40 -0700643 memset(&m_cmp,0,sizeof(m_cmp));
644 memset(&m_cb,0,sizeof(m_cb));
645 memset (&drv_ctx,0,sizeof(drv_ctx));
646 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
647 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
648 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +0530649 memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
Arun Menon906de572013-06-18 17:01:40 -0700650 m_demux_entries = 0;
651 msg_thread_id = 0;
652 async_thread_id = 0;
653 msg_thread_created = false;
654 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700655#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700656 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700657#endif
Arun Menon906de572013-06-18 17:01:40 -0700658 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Maheshwar Ajjad2df2182013-10-24 19:20:34 +0530659 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -0700660 drv_ctx.timestamp_adjust = false;
661 drv_ctx.video_driver_fd = -1;
662 m_vendor_config.pData = NULL;
663 pthread_mutex_init(&m_lock, NULL);
664 pthread_mutex_init(&c_lock, NULL);
665 sem_init(&m_cmd_lock,0,0);
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -0700666 sem_init(&m_safe_flush, 0, 0);
Arun Menon906de572013-06-18 17:01:40 -0700667 streaming[CAPTURE_PORT] =
668 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700669#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700670 char extradata_value[PROPERTY_VALUE_MAX] = {0};
671 property_get("vidc.dec.debug.extradata", extradata_value, "0");
672 m_debug_extradata = atoi(extradata_value);
673 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700674#endif
Arun Menon906de572013-06-18 17:01:40 -0700675 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
676 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700677 dynamic_buf_mode = false;
678 out_dynamic_list = NULL;
Praveen Chavane78460c2013-12-06 23:16:04 -0800679 is_down_scalar_enabled = false;
Praveen Chavancf924182013-12-06 23:16:23 -0800680 m_smoothstreaming_mode = false;
681 m_smoothstreaming_width = 0;
682 m_smoothstreaming_height = 0;
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530683 is_q6_platform = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700684}
685
Vinay Kalia85793762012-06-14 19:12:34 -0700686static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700687 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
688 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
689 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700690 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
691 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
Arun Menon906de572013-06-18 17:01:40 -0700692 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
Jia Meng1e236c82014-04-03 10:54:39 +0800693 V4L2_EVENT_MSM_VIDC_SYS_ERROR,
694 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD
Vinay Kalia85793762012-06-14 19:12:34 -0700695};
696
697static OMX_ERRORTYPE subscribe_to_events(int fd)
698{
Arun Menon906de572013-06-18 17:01:40 -0700699 OMX_ERRORTYPE eRet = OMX_ErrorNone;
700 struct v4l2_event_subscription sub;
701 int array_sz = sizeof(event_type)/sizeof(int);
702 int i,rc;
703 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700704 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700705 return OMX_ErrorBadParameter;
706 }
Vinay Kalia85793762012-06-14 19:12:34 -0700707
Arun Menon906de572013-06-18 17:01:40 -0700708 for (i = 0; i < array_sz; ++i) {
709 memset(&sub, 0, sizeof(sub));
710 sub.type = event_type[i];
711 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
712 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700713 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700714 break;
715 }
716 }
717 if (i < array_sz) {
718 for (--i; i >=0 ; i--) {
719 memset(&sub, 0, sizeof(sub));
720 sub.type = event_type[i];
721 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
722 if (rc)
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700723 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700724 }
725 eRet = OMX_ErrorNotImplemented;
726 }
727 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700728}
729
730
731static OMX_ERRORTYPE unsubscribe_to_events(int fd)
732{
Arun Menon906de572013-06-18 17:01:40 -0700733 OMX_ERRORTYPE eRet = OMX_ErrorNone;
734 struct v4l2_event_subscription sub;
735 int array_sz = sizeof(event_type)/sizeof(int);
736 int i,rc;
737 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700738 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700739 return OMX_ErrorBadParameter;
740 }
Vinay Kalia85793762012-06-14 19:12:34 -0700741
Arun Menon906de572013-06-18 17:01:40 -0700742 for (i = 0; i < array_sz; ++i) {
743 memset(&sub, 0, sizeof(sub));
744 sub.type = event_type[i];
745 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
746 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700747 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700748 break;
749 }
750 }
751 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700752}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700753
754/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700755 FUNCTION
756 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700757
Arun Menon906de572013-06-18 17:01:40 -0700758 DESCRIPTION
759 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700760
Arun Menon906de572013-06-18 17:01:40 -0700761 PARAMETERS
762 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700763
Arun Menon906de572013-06-18 17:01:40 -0700764 RETURN VALUE
765 None.
766 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700767omx_vdec::~omx_vdec()
768{
Arun Menon906de572013-06-18 17:01:40 -0700769 m_pmem_info = NULL;
770 struct v4l2_decoder_cmd dec;
771 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
772 if (m_pipe_in) close(m_pipe_in);
773 if (m_pipe_out) close(m_pipe_out);
774 m_pipe_in = -1;
775 m_pipe_out = -1;
776 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
777 if (msg_thread_created)
778 pthread_join(msg_thread_id,NULL);
779 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
780 dec.cmd = V4L2_DEC_CMD_STOP;
781 if (drv_ctx.video_driver_fd >=0 ) {
782 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700783 DEBUG_PRINT_ERROR("STOP Command failed");
Arun Menon906de572013-06-18 17:01:40 -0700784 }
785 if (async_thread_created)
786 pthread_join(async_thread_id,NULL);
787 unsubscribe_to_events(drv_ctx.video_driver_fd);
788 close(drv_ctx.video_driver_fd);
789 pthread_mutex_destroy(&m_lock);
790 pthread_mutex_destroy(&c_lock);
791 sem_destroy(&m_cmd_lock);
792 if (perf_flag) {
793 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
794 dec_time.end();
795 }
796 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700797}
798
Arun Menon906de572013-06-18 17:01:40 -0700799int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
800{
801 struct v4l2_requestbuffers bufreq;
802 int rc = 0;
803 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
804 bufreq.memory = V4L2_MEMORY_USERPTR;
805 bufreq.count = 0;
806 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
807 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530808 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
809 bufreq.memory = V4L2_MEMORY_USERPTR;
810 bufreq.count = 0;
811 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
812 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700813 }
814 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700815}
816
Shalaj Jain273b3e02012-06-22 19:08:03 -0700817/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700818 FUNCTION
819 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700820
Arun Menon906de572013-06-18 17:01:40 -0700821 DESCRIPTION
822 IL Client callbacks are generated through this routine. The decoder
823 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700824
Arun Menon906de572013-06-18 17:01:40 -0700825 PARAMETERS
826 ctxt -- Context information related to the self.
827 id -- Event identifier. This could be any of the following:
828 1. Command completion event
829 2. Buffer done callback event
830 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700831
Arun Menon906de572013-06-18 17:01:40 -0700832 RETURN VALUE
833 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700834
Arun Menon906de572013-06-18 17:01:40 -0700835 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700836void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
837{
Arun Menon906de572013-06-18 17:01:40 -0700838 signed p1; // Parameter - 1
839 signed p2; // Parameter - 2
840 unsigned ident;
841 unsigned qsize=0; // qsize
842 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700843
Arun Menon906de572013-06-18 17:01:40 -0700844 if (!pThis) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700845 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
Arun Menon906de572013-06-18 17:01:40 -0700846 __func__);
847 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700848 }
849
Arun Menon906de572013-06-18 17:01:40 -0700850 // Protect the shared queue data structure
851 do {
852 /*Read the message id's from the queue*/
853 pthread_mutex_lock(&pThis->m_lock);
854 qsize = pThis->m_cmd_q.m_size;
855 if (qsize) {
856 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700857 }
Arun Menon906de572013-06-18 17:01:40 -0700858
859 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
860 qsize = pThis->m_ftb_q.m_size;
861 if (qsize) {
862 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
863 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700864 }
Arun Menon906de572013-06-18 17:01:40 -0700865
866 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
867 qsize = pThis->m_etb_q.m_size;
868 if (qsize) {
869 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
870 }
871 }
872 pthread_mutex_unlock(&pThis->m_lock);
873
874 /*process message if we have one*/
875 if (qsize > 0) {
876 id = ident;
877 switch (id) {
878 case OMX_COMPONENT_GENERATE_EVENT:
879 if (pThis->m_cb.EventHandler) {
880 switch (p1) {
881 case OMX_CommandStateSet:
882 pThis->m_state = (OMX_STATETYPE) p2;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700883 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
Arun Menon906de572013-06-18 17:01:40 -0700884 pThis->m_state);
885 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
886 OMX_EventCmdComplete, p1, p2, NULL);
887 break;
888
889 case OMX_EventError:
890 if (p2 == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700891 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
Arun Menon906de572013-06-18 17:01:40 -0700892 pThis->m_state = (OMX_STATETYPE) p2;
893 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
894 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
895 } else if (p2 == OMX_ErrorHardware) {
896 pThis->omx_report_error();
897 } else {
898 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
899 OMX_EventError, p2, (OMX_U32)NULL, NULL );
900 }
901 break;
902
903 case OMX_CommandPortDisable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700904 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700905 if (BITMASK_PRESENT(&pThis->m_flags,
906 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
907 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
908 break;
909 }
910 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
911 OMX_ERRORTYPE eRet = OMX_ErrorNone;
912 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
913 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700914 DEBUG_PRINT_HIGH("Failed to release output buffers");
Arun Menon906de572013-06-18 17:01:40 -0700915 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
916 pThis->in_reconfig = false;
917 if (eRet != OMX_ErrorNone) {
918 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
919 pThis->omx_report_error();
920 break;
921 }
922 }
923 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
924 OMX_EventCmdComplete, p1, p2, NULL );
925 break;
926 case OMX_CommandPortEnable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700927 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700928 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
929 OMX_EventCmdComplete, p1, p2, NULL );
930 break;
931
932 default:
933 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
934 OMX_EventCmdComplete, p1, p2, NULL );
935 break;
936
937 }
938 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700939 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Arun Menon906de572013-06-18 17:01:40 -0700940 }
941 break;
942 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
943 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
944 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700945 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
Arun Menon906de572013-06-18 17:01:40 -0700946 pThis->omx_report_error ();
947 }
948 break;
Jia Meng1e236c82014-04-03 10:54:39 +0800949 case OMX_COMPONENT_GENERATE_ETB: {
950 OMX_ERRORTYPE iret;
951 iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
952 if (iret == OMX_ErrorInsufficientResources) {
953 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
954 pThis->omx_report_hw_overload ();
955 } else if (iret != OMX_ErrorNone) {
956 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
957 pThis->omx_report_error ();
958 }
Arun Menon906de572013-06-18 17:01:40 -0700959 }
960 break;
961
962 case OMX_COMPONENT_GENERATE_FTB:
963 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
964 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700965 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700966 pThis->omx_report_error ();
967 }
968 break;
969
970 case OMX_COMPONENT_GENERATE_COMMAND:
971 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
972 (OMX_U32)p2,(OMX_PTR)NULL);
973 break;
974
975 case OMX_COMPONENT_GENERATE_EBD:
976
977 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700978 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700979 pThis->omx_report_error ();
980 } else {
981 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
Arun Menon906de572013-06-18 17:01:40 -0700982 pThis->time_stamp_dts.remove_time_stamp(
983 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
984 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
985 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -0700986 }
Deva Ramasubramanian02b0d882014-04-03 14:58:50 -0700987
Arun Menon906de572013-06-18 17:01:40 -0700988 if ( pThis->empty_buffer_done(&pThis->m_cmp,
989 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700990 DEBUG_PRINT_ERROR("empty_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700991 pThis->omx_report_error ();
992 }
Arun Menon906de572013-06-18 17:01:40 -0700993 }
994 break;
995 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
996 int64_t *timestamp = (int64_t *)p1;
997 if (p1) {
998 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
999 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
1000 ?true:false);
1001 free(timestamp);
1002 }
1003 }
1004 break;
1005 case OMX_COMPONENT_GENERATE_FBD:
1006 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001007 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
Arun Menon906de572013-06-18 17:01:40 -07001008 pThis->omx_report_error ();
1009 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
1010 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001011 DEBUG_PRINT_ERROR("fill_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -07001012 pThis->omx_report_error ();
1013 }
1014 break;
1015
1016 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001017 DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001018 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001019 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001020 } else {
1021 pThis->execute_input_flush();
1022 if (pThis->m_cb.EventHandler) {
1023 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001024 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
Arun Menon906de572013-06-18 17:01:40 -07001025 pThis->omx_report_error ();
1026 } else {
1027 /*Check if we need generate event for Flush done*/
1028 if (BITMASK_PRESENT(&pThis->m_flags,
1029 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
1030 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001031 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
Arun Menon906de572013-06-18 17:01:40 -07001032 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1033 OMX_EventCmdComplete,OMX_CommandFlush,
1034 OMX_CORE_INPUT_PORT_INDEX,NULL );
1035 }
1036 if (BITMASK_PRESENT(&pThis->m_flags,
1037 OMX_COMPONENT_IDLE_PENDING)) {
1038 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001039 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
Arun Menon906de572013-06-18 17:01:40 -07001040 pThis->omx_report_error ();
1041 } else {
1042 pThis->streaming[OUTPUT_PORT] = false;
1043 }
1044 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001045 DEBUG_PRINT_LOW("Input flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001046 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1047 OMX_COMPONENT_GENERATE_STOP_DONE);
1048 }
1049 }
1050 }
1051 } else {
1052 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1053 }
1054 }
1055 break;
1056
1057 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001058 DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001059 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001060 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001061 } else {
1062 pThis->execute_output_flush();
1063 if (pThis->m_cb.EventHandler) {
1064 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001065 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
Arun Menon906de572013-06-18 17:01:40 -07001066 pThis->omx_report_error ();
1067 } else {
1068 /*Check if we need generate event for Flush done*/
1069 if (BITMASK_PRESENT(&pThis->m_flags,
1070 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001071 DEBUG_PRINT_LOW("Notify Output Flush done");
Arun Menon906de572013-06-18 17:01:40 -07001072 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1073 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1074 OMX_EventCmdComplete,OMX_CommandFlush,
1075 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1076 }
1077 if (BITMASK_PRESENT(&pThis->m_flags,
1078 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001079 DEBUG_PRINT_LOW("Internal flush complete");
Arun Menon906de572013-06-18 17:01:40 -07001080 BITMASK_CLEAR (&pThis->m_flags,
1081 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1082 if (BITMASK_PRESENT(&pThis->m_flags,
1083 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1084 pThis->post_event(OMX_CommandPortDisable,
1085 OMX_CORE_OUTPUT_PORT_INDEX,
1086 OMX_COMPONENT_GENERATE_EVENT);
1087 BITMASK_CLEAR (&pThis->m_flags,
1088 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
Praneeth Paladugub52072a2013-08-23 13:54:43 -07001089 BITMASK_CLEAR (&pThis->m_flags,
1090 OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Arun Menon906de572013-06-18 17:01:40 -07001091
1092 }
1093 }
1094
1095 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1096 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001097 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
Arun Menon906de572013-06-18 17:01:40 -07001098 pThis->omx_report_error ();
1099 break;
1100 }
1101 pThis->streaming[CAPTURE_PORT] = false;
1102 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001103 DEBUG_PRINT_LOW("Output flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001104 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1105 OMX_COMPONENT_GENERATE_STOP_DONE);
1106 }
1107 }
1108 }
1109 } else {
1110 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1111 }
1112 }
1113 break;
1114
1115 case OMX_COMPONENT_GENERATE_START_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001116 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001117
1118 if (pThis->m_cb.EventHandler) {
1119 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001120 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
Arun Menon906de572013-06-18 17:01:40 -07001121 pThis->omx_report_error ();
1122 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001123 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001124 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001125 DEBUG_PRINT_LOW("Move to executing");
Arun Menon906de572013-06-18 17:01:40 -07001126 // Send the callback now
1127 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1128 pThis->m_state = OMX_StateExecuting;
1129 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1130 OMX_EventCmdComplete,OMX_CommandStateSet,
1131 OMX_StateExecuting, NULL);
1132 } else if (BITMASK_PRESENT(&pThis->m_flags,
1133 OMX_COMPONENT_PAUSE_PENDING)) {
1134 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1135 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001136 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
Arun Menon906de572013-06-18 17:01:40 -07001137 pThis->omx_report_error ();
1138 }
1139 }
1140 }
1141 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001142 DEBUG_PRINT_LOW("Event Handler callback is NULL");
Arun Menon906de572013-06-18 17:01:40 -07001143 }
1144 break;
1145
1146 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001147 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001148 if (pThis->m_cb.EventHandler) {
1149 if (p2 != VDEC_S_SUCCESS) {
1150 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1151 pThis->omx_report_error ();
1152 } else {
1153 pThis->complete_pending_buffer_done_cbs();
1154 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001155 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
Arun Menon906de572013-06-18 17:01:40 -07001156 //Send the callback now
1157 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1158 pThis->m_state = OMX_StatePause;
1159 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1160 OMX_EventCmdComplete,OMX_CommandStateSet,
1161 OMX_StatePause, NULL);
1162 }
1163 }
1164 } else {
1165 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1166 }
1167
1168 break;
1169
1170 case OMX_COMPONENT_GENERATE_RESUME_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001171 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001172 if (pThis->m_cb.EventHandler) {
1173 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001174 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
Arun Menon906de572013-06-18 17:01:40 -07001175 pThis->omx_report_error ();
1176 } else {
1177 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001178 DEBUG_PRINT_LOW("Moving the decoder to execute state");
Arun Menon906de572013-06-18 17:01:40 -07001179 // Send the callback now
1180 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1181 pThis->m_state = OMX_StateExecuting;
1182 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1183 OMX_EventCmdComplete,OMX_CommandStateSet,
1184 OMX_StateExecuting,NULL);
1185 }
1186 }
1187 } else {
1188 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1189 }
1190
1191 break;
1192
1193 case OMX_COMPONENT_GENERATE_STOP_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001194 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001195 if (pThis->m_cb.EventHandler) {
1196 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001197 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
Arun Menon906de572013-06-18 17:01:40 -07001198 pThis->omx_report_error ();
1199 } else {
1200 pThis->complete_pending_buffer_done_cbs();
1201 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001202 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001203 // Send the callback now
1204 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1205 pThis->m_state = OMX_StateIdle;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001206 DEBUG_PRINT_LOW("Move to Idle State");
Arun Menon906de572013-06-18 17:01:40 -07001207 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1208 OMX_EventCmdComplete,OMX_CommandStateSet,
1209 OMX_StateIdle,NULL);
1210 }
1211 }
1212 } else {
1213 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1214 }
1215
1216 break;
1217
1218 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
Arun Menon906de572013-06-18 17:01:40 -07001219 if (p2 == OMX_IndexParamPortDefinition) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301220 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07001221 pThis->in_reconfig = true;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301222
1223 } else if (p2 == OMX_IndexConfigCommonOutputCrop) {
1224 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301225
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301226 /* Check if resolution is changed in smooth streaming mode */
1227 if (pThis->m_smoothstreaming_mode &&
1228 (pThis->framesize.nWidth !=
1229 pThis->drv_ctx.video_resolution.frame_width) ||
1230 (pThis->framesize.nHeight !=
1231 pThis->drv_ctx.video_resolution.frame_height)) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301232
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301233 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
1234 pThis->framesize.nWidth,
1235 pThis->framesize.nHeight,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301236 pThis->drv_ctx.video_resolution.frame_width,
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301237 pThis->drv_ctx.video_resolution.frame_height);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301238
1239 /* Update new resolution */
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301240 pThis->framesize.nWidth =
1241 pThis->drv_ctx.video_resolution.frame_width;
1242 pThis->framesize.nHeight =
1243 pThis->drv_ctx.video_resolution.frame_height;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301244
1245 /* Update C2D with new resolution */
1246 if (!pThis->client_buffers.update_buffer_req()) {
1247 DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
1248 }
1249 }
1250
1251 /* Update new crop information */
1252 pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
1253 pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
1254 pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
1255 pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
1256
1257 /* Validate the new crop information */
1258 if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
1259 pThis->drv_ctx.video_resolution.frame_width) {
1260
1261 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
1262 pThis->rectangle.nLeft, pThis->rectangle.nWidth,
1263 pThis->drv_ctx.video_resolution.frame_width);
1264 pThis->rectangle.nLeft = 0;
1265
1266 if (pThis->rectangle.nWidth >
1267 pThis->drv_ctx.video_resolution.frame_width) {
1268
1269 DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
1270 pThis->rectangle.nWidth,
1271 pThis->drv_ctx.video_resolution.frame_width);
1272 pThis->rectangle.nWidth =
1273 pThis->drv_ctx.video_resolution.frame_width;
1274 }
1275 }
1276 if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
1277 pThis->drv_ctx.video_resolution.frame_height) {
1278
1279 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
1280 pThis->rectangle.nTop, pThis->rectangle.nHeight,
1281 pThis->drv_ctx.video_resolution.frame_height);
1282 pThis->rectangle.nTop = 0;
1283
1284 if (pThis->rectangle.nHeight >
1285 pThis->drv_ctx.video_resolution.frame_height) {
1286
1287 DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
1288 pThis->rectangle.nHeight,
1289 pThis->drv_ctx.video_resolution.frame_height);
1290 pThis->rectangle.nHeight =
1291 pThis->drv_ctx.video_resolution.frame_height;
1292 }
1293 }
1294 DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
1295 pThis->rectangle.nLeft, pThis->rectangle.nTop,
1296 pThis->rectangle.nWidth, pThis->rectangle.nHeight);
1297 } else {
1298 DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
1299 break;
Arun Menon906de572013-06-18 17:01:40 -07001300 }
1301 if (pThis->m_cb.EventHandler) {
1302 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1303 OMX_EventPortSettingsChanged, p1, p2, NULL );
1304 } else {
1305 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1306 }
Arun Menon906de572013-06-18 17:01:40 -07001307 break;
1308
1309 case OMX_COMPONENT_GENERATE_EOS_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001310 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001311 if (pThis->m_cb.EventHandler) {
1312 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1313 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1314 } else {
1315 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1316 }
1317 pThis->prev_ts = LLONG_MAX;
1318 pThis->rst_prev_ts = true;
1319 break;
1320
1321 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001322 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
Arun Menon906de572013-06-18 17:01:40 -07001323 pThis->omx_report_error ();
1324 break;
1325
1326 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001327 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
Arun Menon906de572013-06-18 17:01:40 -07001328 pThis->omx_report_unsupported_setting();
1329 break;
1330
Deepak Verma24720fb2014-01-29 16:57:40 +05301331 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
1332 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
1333 pThis->omx_report_hw_overload();
1334 break;
1335
Arun Menon906de572013-06-18 17:01:40 -07001336 default:
1337 break;
1338 }
1339 }
1340 pthread_mutex_lock(&pThis->m_lock);
1341 qsize = pThis->m_cmd_q.m_size;
1342 if (pThis->m_state != OMX_StatePause)
1343 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1344 pthread_mutex_unlock(&pThis->m_lock);
1345 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001346
1347}
1348
Vinay Kaliab9e98102013-04-02 19:31:43 -07001349int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001350{
Arun Menon906de572013-06-18 17:01:40 -07001351 int format_changed = 0;
Surajit Podderd2644d52013-08-28 17:59:06 +05301352 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1353 (width != (int)drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001354 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
Arun Menon906de572013-06-18 17:01:40 -07001355 width, drv_ctx.video_resolution.frame_width,
1356 height,drv_ctx.video_resolution.frame_height);
1357 format_changed = 1;
1358 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001359 drv_ctx.video_resolution.frame_height = height;
1360 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001361 drv_ctx.video_resolution.scan_lines = scan_lines;
1362 drv_ctx.video_resolution.stride = stride;
Pushkaraj Patil41588352014-02-25 20:51:34 +05301363 if(!is_down_scalar_enabled) {
1364 rectangle.nLeft = 0;
1365 rectangle.nTop = 0;
1366 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1367 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
1368 }
Arun Menon906de572013-06-18 17:01:40 -07001369 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001370}
1371
Arun Menon6836ba02013-02-19 20:37:40 -08001372OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1373{
Arun Menon906de572013-06-18 17:01:40 -07001374 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1375 OMX_MAX_STRINGNAME_SIZE) &&
1376 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1377 m_decoder_capability.max_width = 1280;
1378 m_decoder_capability.max_height = 720;
1379 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1380 }
Arun Menon888aa852013-05-30 11:24:42 -07001381
Arun Menon906de572013-06-18 17:01:40 -07001382 if ((drv_ctx.video_resolution.frame_width *
1383 drv_ctx.video_resolution.frame_height >
1384 m_decoder_capability.max_width *
1385 m_decoder_capability.max_height) ||
1386 (drv_ctx.video_resolution.frame_width*
1387 drv_ctx.video_resolution.frame_height <
1388 m_decoder_capability.min_width *
1389 m_decoder_capability.min_height)) {
1390 DEBUG_PRINT_ERROR(
1391 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1392 drv_ctx.video_resolution.frame_width,
1393 drv_ctx.video_resolution.frame_height,
1394 m_decoder_capability.min_width,
1395 m_decoder_capability.min_height,
1396 m_decoder_capability.max_width,
1397 m_decoder_capability.max_height);
1398 return OMX_ErrorUnsupportedSetting;
1399 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001400 DEBUG_PRINT_HIGH("video session supported");
Arun Menon906de572013-06-18 17:01:40 -07001401 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001402}
1403
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001404int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1405{
1406 if (m_debug.in_buffer_log && !m_debug.infile) {
1407 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1408 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1409 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1410 }
1411 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1412 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); }
1413 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1414 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
1415 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1416 }
1417 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
1418 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1419 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1420 }
1421 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1422 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1423 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1424 }
1425 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1426 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1427 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1428 }
1429 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1430 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1431 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1432 }
1433 m_debug.infile = fopen (m_debug.infile_name, "ab");
1434 if (!m_debug.infile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001435 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001436 m_debug.infile_name[0] = '\0';
1437 return -1;
1438 }
1439 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1440 struct ivf_file_header {
1441 OMX_U8 signature[4]; //='DKIF';
1442 OMX_U8 version ; //= 0;
1443 OMX_U8 headersize ; //= 32;
1444 OMX_U32 FourCC;
1445 OMX_U8 width;
1446 OMX_U8 height;
1447 OMX_U32 rate;
1448 OMX_U32 scale;
1449 OMX_U32 length;
1450 OMX_U8 unused[4];
1451 } file_header;
1452
1453 memset((void *)&file_header,0,sizeof(file_header));
1454 file_header.signature[0] = 'D';
1455 file_header.signature[1] = 'K';
1456 file_header.signature[2] = 'I';
1457 file_header.signature[3] = 'F';
1458 file_header.version = 0;
1459 file_header.headersize = 32;
1460 file_header.FourCC = 0x30385056;
1461 fwrite((const char *)&file_header,
1462 sizeof(file_header),1,m_debug.infile);
1463 }
1464 }
1465 if (m_debug.infile && buffer_addr && buffer_len) {
1466 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1467 struct vp8_ivf_frame_header {
1468 OMX_U32 framesize;
1469 OMX_U32 timestamp_lo;
1470 OMX_U32 timestamp_hi;
1471 } vp8_frame_header;
1472 vp8_frame_header.framesize = buffer_len;
1473 /* Currently FW doesn't use timestamp values */
1474 vp8_frame_header.timestamp_lo = 0;
1475 vp8_frame_header.timestamp_hi = 0;
1476 fwrite((const char *)&vp8_frame_header,
1477 sizeof(vp8_frame_header),1,m_debug.infile);
1478 }
1479 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1480 }
1481 return 0;
1482}
1483
1484int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1485 if (m_debug.out_buffer_log && !m_debug.outfile) {
1486 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1487 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1488 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1489 if (!m_debug.outfile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001490 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001491 m_debug.outfile_name[0] = '\0';
1492 return -1;
1493 }
1494 }
1495 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1496 int buf_index = buffer - m_out_mem_ptr;
1497 int stride = drv_ctx.video_resolution.stride;
1498 int scanlines = drv_ctx.video_resolution.scan_lines;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301499 if (m_smoothstreaming_mode) {
1500 stride = drv_ctx.video_resolution.frame_width;
1501 scanlines = drv_ctx.video_resolution.frame_height;
1502 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
1503 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
1504 }
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001505 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1506 unsigned i;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301507 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
1508 drv_ctx.video_resolution.frame_width,
1509 drv_ctx.video_resolution.frame_height, stride, scanlines);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001510 int bytes_written = 0;
1511 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1512 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1513 temp += stride;
1514 }
1515 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1516 int stride_c = stride;
1517 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1518 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1519 temp += stride_c;
1520 }
1521 }
1522 return 0;
1523}
1524
Shalaj Jain273b3e02012-06-22 19:08:03 -07001525/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001526 FUNCTION
1527 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001528
Arun Menon906de572013-06-18 17:01:40 -07001529 DESCRIPTION
1530 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001531
Arun Menon906de572013-06-18 17:01:40 -07001532 PARAMETERS
1533 ctxt -- Context information related to the self.
1534 id -- Event identifier. This could be any of the following:
1535 1. Command completion event
1536 2. Buffer done callback event
1537 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001538
Arun Menon906de572013-06-18 17:01:40 -07001539 RETURN VALUE
1540 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001541
Arun Menon906de572013-06-18 17:01:40 -07001542 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001543OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1544{
1545
Arun Menon906de572013-06-18 17:01:40 -07001546 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1547 struct v4l2_fmtdesc fdesc;
1548 struct v4l2_format fmt;
1549 struct v4l2_requestbuffers bufreq;
1550 struct v4l2_control control;
1551 struct v4l2_frmsizeenum frmsize;
1552 unsigned int alignment = 0,buffer_size = 0;
1553 int fds[2];
1554 int r,ret=0;
1555 bool codec_ambiguous = false;
1556 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Jia Meng3a3c6492013-12-19 17:16:52 +08001557 char property_value[PROPERTY_VALUE_MAX] = {0};
Sachin Shahc82a18f2013-03-29 14:45:38 -07001558
1559#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001560 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001561 property_get("ro.board.platform", platform_name, "0");
1562 if (!strncmp(platform_name, "msm8610", 7)) {
1563 device_name = (OMX_STRING)"/dev/video/q6_dec";
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301564 is_q6_platform = true;
1565 maxSmoothStreamingWidth = 1280;
1566 maxSmoothStreamingHeight = 720;
Arun Menon906de572013-06-18 17:01:40 -07001567 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001568#endif
1569
Arun Menon906de572013-06-18 17:01:40 -07001570 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1571 struct v4l2_control control;
1572 secure_mode = true;
1573 arbitrary_bytes = false;
1574 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301575 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
1576 OMX_MAX_STRINGNAME_SIZE)){
1577 secure_mode = true;
1578 arbitrary_bytes = false;
1579 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
Arun Menon906de572013-06-18 17:01:40 -07001580 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001581
Arun Menon906de572013-06-18 17:01:40 -07001582 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001583
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001584 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d",
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001585 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001586
Arun Menon906de572013-06-18 17:01:40 -07001587 if (drv_ctx.video_driver_fd == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001588 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
Arun Menon906de572013-06-18 17:01:40 -07001589 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1590 close(0);
1591 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001592
Arun Menon906de572013-06-18 17:01:40 -07001593 if (drv_ctx.video_driver_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001594 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
Arun Menon906de572013-06-18 17:01:40 -07001595 return OMX_ErrorInsufficientResources;
1596 }
1597 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1598 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001599
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001600 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001601 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001602 async_thread_created = true;
1603 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1604 }
1605 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001606 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
Arun Menon906de572013-06-18 17:01:40 -07001607 async_thread_created = false;
1608 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001609 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001610
Shalaj Jain273b3e02012-06-22 19:08:03 -07001611#ifdef OUTPUT_EXTRADATA_LOG
Deva Ramasubramanianee6f1f42014-01-31 12:49:18 -08001612 outputExtradataFile = fopen (output_extradata_filename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001613#endif
1614
Arun Menon906de572013-06-18 17:01:40 -07001615 // Copy the role information which provides the decoder kind
1616 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001617
Arun Menon906de572013-06-18 17:01:40 -07001618 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1619 OMX_MAX_STRINGNAME_SIZE)) {
1620 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1621 OMX_MAX_STRINGNAME_SIZE);
1622 drv_ctx.timestamp_adjust = true;
1623 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1624 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1625 output_capability=V4L2_PIX_FMT_MPEG4;
Deva Ramasubramanian14b50b42014-09-29 12:29:39 -07001626 ignore_not_coded_vops = false;
Arun Menon906de572013-06-18 17:01:40 -07001627 /*Initialize Start Code for MPEG4*/
1628 codec_type_parse = CODEC_TYPE_MPEG4;
1629 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001630 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1631 OMX_MAX_STRINGNAME_SIZE)) {
1632 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1633 OMX_MAX_STRINGNAME_SIZE);
1634 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1635 output_capability = V4L2_PIX_FMT_MPEG2;
1636 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1637 /*Initialize Start Code for MPEG2*/
1638 codec_type_parse = CODEC_TYPE_MPEG2;
1639 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001640 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1641 OMX_MAX_STRINGNAME_SIZE)) {
1642 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001643 DEBUG_PRINT_LOW("H263 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001644 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1645 eCompressionFormat = OMX_VIDEO_CodingH263;
1646 output_capability = V4L2_PIX_FMT_H263;
1647 codec_type_parse = CODEC_TYPE_H263;
1648 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001649 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1650 OMX_MAX_STRINGNAME_SIZE)) {
1651 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001652 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001653 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1654 output_capability = V4L2_PIX_FMT_DIVX_311;
1655 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1656 codec_type_parse = CODEC_TYPE_DIVX;
Deva Ramasubramanian14b50b42014-09-29 12:29:39 -07001657 ignore_not_coded_vops = true;
Arun Menon906de572013-06-18 17:01:40 -07001658 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001659
Arun Menon906de572013-06-18 17:01:40 -07001660 eRet = createDivxDrmContext();
1661 if (eRet != OMX_ErrorNone) {
1662 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1663 return eRet;
1664 }
1665 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1666 OMX_MAX_STRINGNAME_SIZE)) {
1667 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001668 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001669 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1670 output_capability = V4L2_PIX_FMT_DIVX;
1671 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1672 codec_type_parse = CODEC_TYPE_DIVX;
1673 codec_ambiguous = true;
Deva Ramasubramanian14b50b42014-09-29 12:29:39 -07001674 ignore_not_coded_vops = true;
Arun Menon906de572013-06-18 17:01:40 -07001675 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001676
Arun Menon906de572013-06-18 17:01:40 -07001677 eRet = createDivxDrmContext();
1678 if (eRet != OMX_ErrorNone) {
1679 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1680 return eRet;
1681 }
1682 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1683 OMX_MAX_STRINGNAME_SIZE)) {
1684 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001685 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001686 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1687 output_capability = V4L2_PIX_FMT_DIVX;
1688 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1689 codec_type_parse = CODEC_TYPE_DIVX;
1690 codec_ambiguous = true;
Deva Ramasubramanian14b50b42014-09-29 12:29:39 -07001691 ignore_not_coded_vops = true;
Arun Menon906de572013-06-18 17:01:40 -07001692 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001693
Arun Menon906de572013-06-18 17:01:40 -07001694 eRet = createDivxDrmContext();
1695 if (eRet != OMX_ErrorNone) {
1696 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1697 return eRet;
1698 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001699
Arun Menon906de572013-06-18 17:01:40 -07001700 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1701 OMX_MAX_STRINGNAME_SIZE)) {
1702 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1703 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1704 output_capability=V4L2_PIX_FMT_H264;
1705 eCompressionFormat = OMX_VIDEO_CodingAVC;
1706 codec_type_parse = CODEC_TYPE_H264;
1707 m_frame_parser.init_start_codes (codec_type_parse);
1708 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001709 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1710 OMX_MAX_STRINGNAME_SIZE)) {
1711 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1712 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1713 eCompressionFormat = OMX_VIDEO_CodingWMV;
1714 codec_type_parse = CODEC_TYPE_VC1;
1715 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1716 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001717 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1718 OMX_MAX_STRINGNAME_SIZE)) {
1719 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1720 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1721 eCompressionFormat = OMX_VIDEO_CodingWMV;
1722 codec_type_parse = CODEC_TYPE_VC1;
1723 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1724 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001725 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1726 OMX_MAX_STRINGNAME_SIZE)) {
1727 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1728 output_capability=V4L2_PIX_FMT_VP8;
Praveen Chavan76b71c32014-07-10 18:10:51 -07001729 eCompressionFormat = OMX_VIDEO_CodingVP8;
Arun Menon906de572013-06-18 17:01:40 -07001730 codec_type_parse = CODEC_TYPE_VP8;
1731 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001732
Arun Menon906de572013-06-18 17:01:40 -07001733 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001734 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07001735 eRet = OMX_ErrorInvalidComponentName;
1736 }
Arun Menon906de572013-06-18 17:01:40 -07001737 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001738
Arun Menon906de572013-06-18 17:01:40 -07001739 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001740 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1741 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1742 if (!client_buffers.set_color_format(dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001743 DEBUG_PRINT_ERROR("Setting color format failed");
Vinay Kaliada4f4422013-01-09 10:45:03 -08001744 eRet = OMX_ErrorInsufficientResources;
1745 }
1746
Arun Menon906de572013-06-18 17:01:40 -07001747 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001748
Arun Menon906de572013-06-18 17:01:40 -07001749 struct v4l2_capability cap;
1750 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1751 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001752 DEBUG_PRINT_ERROR("Failed to query capabilities");
Arun Menon906de572013-06-18 17:01:40 -07001753 /*TODO: How to handle this case */
1754 } else {
1755 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001756 " version = %d, capabilities = %x", cap.driver, cap.card,
Arun Menon906de572013-06-18 17:01:40 -07001757 cap.bus_info, cap.version, cap.capabilities);
1758 }
1759 ret=0;
1760 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1761 fdesc.index=0;
1762 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001763 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001764 fdesc.pixelformat, fdesc.flags);
1765 fdesc.index++;
1766 }
1767 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1768 fdesc.index=0;
1769 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001770
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001771 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001772 fdesc.pixelformat, fdesc.flags);
1773 fdesc.index++;
1774 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001775 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001776 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1777 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1778 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1779 fmt.fmt.pix_mp.pixelformat = output_capability;
1780 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1781 if (ret) {
1782 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001783 DEBUG_PRINT_ERROR("Failed to set format on output port");
Arun Menon906de572013-06-18 17:01:40 -07001784 return OMX_ErrorInsufficientResources;
1785 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001786 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001787 if (codec_ambiguous) {
1788 if (output_capability == V4L2_PIX_FMT_DIVX) {
1789 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001790
Arun Menon906de572013-06-18 17:01:40 -07001791 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1792 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1793 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1794 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1795 } else {
1796 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1797 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001798
Arun Menon906de572013-06-18 17:01:40 -07001799 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1800 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1801 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001802 DEBUG_PRINT_ERROR("Failed to set divx version");
Arun Menon906de572013-06-18 17:01:40 -07001803 }
1804 } else {
1805 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1806 }
1807 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001808
Jia Meng3a3c6492013-12-19 17:16:52 +08001809 property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
1810 m_conceal_color= atoi(property_value);
1811 DEBUG_PRINT_HIGH("trying to set 0x%x as conceal color\n",m_conceal_color);
1812 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
1813 control.value = m_conceal_color;
1814 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1815 if (ret) {
1816 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
1817 }
1818
Arun Menon906de572013-06-18 17:01:40 -07001819 //Get the hardware capabilities
1820 memset((void *)&frmsize,0,sizeof(frmsize));
1821 frmsize.index = 0;
1822 frmsize.pixel_format = output_capability;
1823 ret = ioctl(drv_ctx.video_driver_fd,
1824 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1825 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001826 DEBUG_PRINT_ERROR("Failed to get framesizes");
Arun Menon906de572013-06-18 17:01:40 -07001827 return OMX_ErrorHardware;
1828 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001829
Arun Menon906de572013-06-18 17:01:40 -07001830 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1831 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1832 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1833 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1834 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1835 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001836
Arun Menon906de572013-06-18 17:01:40 -07001837 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1838 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1839 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1840 fmt.fmt.pix_mp.pixelformat = capture_capability;
1841 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1842 if (ret) {
1843 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001844 DEBUG_PRINT_ERROR("Failed to set format on capture port");
Arun Menon906de572013-06-18 17:01:40 -07001845 }
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301846 memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
1847 framesize.nWidth = drv_ctx.video_resolution.frame_width;
1848 framesize.nHeight = drv_ctx.video_resolution.frame_height;
1849
1850 memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
1851 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1852 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
1853
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001854 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001855 if (secure_mode) {
1856 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1857 control.value = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001858 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001859 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1860 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001861 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001862 return OMX_ErrorInsufficientResources;
1863 }
1864 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001865
Arun Menon906de572013-06-18 17:01:40 -07001866 /*Get the Buffer requirements for input and output ports*/
1867 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1868 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1869 if (secure_mode) {
1870 drv_ctx.op_buf.alignment=SZ_1M;
1871 drv_ctx.ip_buf.alignment=SZ_1M;
1872 } else {
1873 drv_ctx.op_buf.alignment=SZ_4K;
1874 drv_ctx.ip_buf.alignment=SZ_4K;
1875 }
1876 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1877 drv_ctx.extradata = 0;
1878 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1879 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1880 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1881 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1882 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001883
Vinay Kalia5713bb32013-01-16 18:39:59 -08001884 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001885#ifdef DEFAULT_EXTRADATA
Arun Menonf8908a62013-12-20 17:36:21 -08001886 if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
1887 OMX_MAX_STRINGNAME_SIZE) && (eRet == OMX_ErrorNone))
1888 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001889#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001890 eRet=get_buffer_req(&drv_ctx.ip_buf);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001891 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
Vinay Kalia5713bb32013-01-16 18:39:59 -08001892 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001893 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1894 if (m_frame_parser.mutils == NULL) {
1895 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001896
Arun Menon906de572013-06-18 17:01:40 -07001897 if (m_frame_parser.mutils == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001898 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001899 eRet = OMX_ErrorInsufficientResources;
1900 } else {
1901 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1902 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1903 h264_scratch.nFilledLen = 0;
1904 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001905
Arun Menon906de572013-06-18 17:01:40 -07001906 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001907 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001908 return OMX_ErrorInsufficientResources;
1909 }
1910 m_frame_parser.mutils->initialize_frame_checking_environment();
1911 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1912 }
1913 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001914
Arun Menon906de572013-06-18 17:01:40 -07001915 h264_parser = new h264_stream_parser();
1916 if (!h264_parser) {
1917 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1918 eRet = OMX_ErrorInsufficientResources;
1919 }
1920 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001921
Arun Menon906de572013-06-18 17:01:40 -07001922 if (pipe(fds)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001923 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001924 eRet = OMX_ErrorInsufficientResources;
1925 } else {
1926 int temp1[2];
1927 if (fds[0] == 0 || fds[1] == 0) {
1928 if (pipe (temp1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001929 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001930 return OMX_ErrorInsufficientResources;
1931 }
1932 //close (fds[0]);
1933 //close (fds[1]);
1934 fds[0] = temp1 [0];
1935 fds[1] = temp1 [1];
1936 }
1937 m_pipe_in = fds[0];
1938 m_pipe_out = fds[1];
1939 msg_thread_created = true;
1940 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001941
Arun Menon906de572013-06-18 17:01:40 -07001942 if (r < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001943 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001944 msg_thread_created = false;
1945 eRet = OMX_ErrorInsufficientResources;
1946 }
1947 }
1948 }
1949
1950 if (eRet != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001951 DEBUG_PRINT_ERROR("Component Init Failed");
Arun Menon906de572013-06-18 17:01:40 -07001952 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001953 DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
Arun Menon906de572013-06-18 17:01:40 -07001954 }
1955 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1956 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001957}
1958
1959/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001960 FUNCTION
1961 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001962
Arun Menon906de572013-06-18 17:01:40 -07001963 DESCRIPTION
1964 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001965
Arun Menon906de572013-06-18 17:01:40 -07001966 PARAMETERS
1967 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001968
Arun Menon906de572013-06-18 17:01:40 -07001969 RETURN VALUE
1970 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001971
Arun Menon906de572013-06-18 17:01:40 -07001972 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001973OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001974(
1975 OMX_IN OMX_HANDLETYPE hComp,
1976 OMX_OUT OMX_STRING componentName,
1977 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1978 OMX_OUT OMX_VERSIONTYPE* specVersion,
1979 OMX_OUT OMX_UUIDTYPE* componentUUID
1980 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001981{
Arun Menon906de572013-06-18 17:01:40 -07001982 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001983 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001984 return OMX_ErrorInvalidState;
1985 }
Arun Menon906de572013-06-18 17:01:40 -07001986 /* TBD -- Return the proper version */
1987 if (specVersion) {
1988 specVersion->nVersion = OMX_SPEC_VERSION;
1989 }
1990 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001991}
1992/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001993 FUNCTION
1994 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001995
Arun Menon906de572013-06-18 17:01:40 -07001996 DESCRIPTION
1997 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001998
Arun Menon906de572013-06-18 17:01:40 -07001999 PARAMETERS
2000 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002001
Arun Menon906de572013-06-18 17:01:40 -07002002 RETURN VALUE
2003 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002004
Arun Menon906de572013-06-18 17:01:40 -07002005 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002006OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002007 OMX_IN OMX_COMMANDTYPE cmd,
2008 OMX_IN OMX_U32 param1,
2009 OMX_IN OMX_PTR cmdData
2010 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002011{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002012 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07002013 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002014 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002015 return OMX_ErrorInvalidState;
2016 }
2017 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07002018 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002019 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07002020 "to invalid port: %lu", param1);
2021 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002022 }
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -07002023
Shalaj Jain273b3e02012-06-22 19:08:03 -07002024 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
2025 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002026 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002027 return OMX_ErrorNone;
2028}
2029
2030/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002031 FUNCTION
2032 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07002033
Arun Menon906de572013-06-18 17:01:40 -07002034 DESCRIPTION
2035 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07002036
Arun Menon906de572013-06-18 17:01:40 -07002037 PARAMETERS
2038 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002039
Arun Menon906de572013-06-18 17:01:40 -07002040 RETURN VALUE
2041 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002042
Arun Menon906de572013-06-18 17:01:40 -07002043 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002044OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002045 OMX_IN OMX_COMMANDTYPE cmd,
2046 OMX_IN OMX_U32 param1,
2047 OMX_IN OMX_PTR cmdData
2048 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002049{
Arun Menon906de572013-06-18 17:01:40 -07002050 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2051 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
2052 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002053
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002054 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
2055 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07002056 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002057
Arun Menon906de572013-06-18 17:01:40 -07002058 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002059 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
2060 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07002061 /***************************/
2062 /* Current State is Loaded */
2063 /***************************/
2064 if (m_state == OMX_StateLoaded) {
2065 if (eState == OMX_StateIdle) {
2066 //if all buffers are allocated or all ports disabled
2067 if (allocate_done() ||
2068 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002069 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002070 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002071 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002072 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
2073 // Skip the event notification
2074 bFlag = 0;
2075 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002076 }
Arun Menon906de572013-06-18 17:01:40 -07002077 /* Requesting transition from Loaded to Loaded */
2078 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002079 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002080 post_event(OMX_EventError,OMX_ErrorSameState,\
2081 OMX_COMPONENT_GENERATE_EVENT);
2082 eRet = OMX_ErrorSameState;
2083 }
2084 /* Requesting transition from Loaded to WaitForResources */
2085 else if (eState == OMX_StateWaitForResources) {
2086 /* Since error is None , we will post an event
2087 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002088 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002089 }
2090 /* Requesting transition from Loaded to Executing */
2091 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002092 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002093 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2094 OMX_COMPONENT_GENERATE_EVENT);
2095 eRet = OMX_ErrorIncorrectStateTransition;
2096 }
2097 /* Requesting transition from Loaded to Pause */
2098 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002099 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002100 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2101 OMX_COMPONENT_GENERATE_EVENT);
2102 eRet = OMX_ErrorIncorrectStateTransition;
2103 }
2104 /* Requesting transition from Loaded to Invalid */
2105 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002106 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002107 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2108 eRet = OMX_ErrorInvalidState;
2109 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002110 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07002111 eState);
2112 eRet = OMX_ErrorBadParameter;
2113 }
2114 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002115
Arun Menon906de572013-06-18 17:01:40 -07002116 /***************************/
2117 /* Current State is IDLE */
2118 /***************************/
2119 else if (m_state == OMX_StateIdle) {
2120 if (eState == OMX_StateLoaded) {
2121 if (release_done()) {
2122 /*
2123 Since error is None , we will post an event at the end
2124 of this function definition
2125 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002126 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002127 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002128 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002129 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2130 // Skip the event notification
2131 bFlag = 0;
2132 }
2133 }
2134 /* Requesting transition from Idle to Executing */
2135 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002136 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002137 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2138 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002139 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002140 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002141 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07002142 }
2143 /* Requesting transition from Idle to Idle */
2144 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002145 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002146 post_event(OMX_EventError,OMX_ErrorSameState,\
2147 OMX_COMPONENT_GENERATE_EVENT);
2148 eRet = OMX_ErrorSameState;
2149 }
2150 /* Requesting transition from Idle to WaitForResources */
2151 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002152 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002153 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2154 OMX_COMPONENT_GENERATE_EVENT);
2155 eRet = OMX_ErrorIncorrectStateTransition;
2156 }
2157 /* Requesting transition from Idle to Pause */
2158 else if (eState == OMX_StatePause) {
2159 /*To pause the Video core we need to start the driver*/
2160 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2161 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002162 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002163 omx_report_error ();
2164 eRet = OMX_ErrorHardware;
2165 } else {
2166 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002167 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002168 bFlag = 0;
2169 }
2170 }
2171 /* Requesting transition from Idle to Invalid */
2172 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002173 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002174 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2175 eRet = OMX_ErrorInvalidState;
2176 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002177 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002178 eRet = OMX_ErrorBadParameter;
2179 }
2180 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002181
Arun Menon906de572013-06-18 17:01:40 -07002182 /******************************/
2183 /* Current State is Executing */
2184 /******************************/
2185 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002186 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002187 /* Requesting transition from Executing to Idle */
2188 if (eState == OMX_StateIdle) {
2189 /* Since error is None , we will post an event
2190 at the end of this function definition
2191 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002192 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002193 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2194 if (!sem_posted) {
2195 sem_posted = 1;
2196 sem_post (&m_cmd_lock);
2197 execute_omx_flush(OMX_ALL);
2198 }
2199 bFlag = 0;
2200 }
2201 /* Requesting transition from Executing to Paused */
2202 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002203 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002204 m_state = OMX_StatePause;
2205 bFlag = 1;
2206 }
2207 /* Requesting transition from Executing to Loaded */
2208 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002209 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002210 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2211 OMX_COMPONENT_GENERATE_EVENT);
2212 eRet = OMX_ErrorIncorrectStateTransition;
2213 }
2214 /* Requesting transition from Executing to WaitForResources */
2215 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002216 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002217 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2218 OMX_COMPONENT_GENERATE_EVENT);
2219 eRet = OMX_ErrorIncorrectStateTransition;
2220 }
2221 /* Requesting transition from Executing to Executing */
2222 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002223 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002224 post_event(OMX_EventError,OMX_ErrorSameState,\
2225 OMX_COMPONENT_GENERATE_EVENT);
2226 eRet = OMX_ErrorSameState;
2227 }
2228 /* Requesting transition from Executing to Invalid */
2229 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002230 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002231 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2232 eRet = OMX_ErrorInvalidState;
2233 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002234 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002235 eRet = OMX_ErrorBadParameter;
2236 }
2237 }
2238 /***************************/
2239 /* Current State is Pause */
2240 /***************************/
2241 else if (m_state == OMX_StatePause) {
2242 /* Requesting transition from Pause to Executing */
2243 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002244 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002245 m_state = OMX_StateExecuting;
2246 bFlag = 1;
2247 }
2248 /* Requesting transition from Pause to Idle */
2249 else if (eState == OMX_StateIdle) {
2250 /* Since error is None , we will post an event
2251 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002252 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002253 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2254 if (!sem_posted) {
2255 sem_posted = 1;
2256 sem_post (&m_cmd_lock);
2257 execute_omx_flush(OMX_ALL);
2258 }
2259 bFlag = 0;
2260 }
2261 /* Requesting transition from Pause to loaded */
2262 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002263 DEBUG_PRINT_ERROR("Pause --> loaded");
Arun Menon906de572013-06-18 17:01:40 -07002264 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2265 OMX_COMPONENT_GENERATE_EVENT);
2266 eRet = OMX_ErrorIncorrectStateTransition;
2267 }
2268 /* Requesting transition from Pause to WaitForResources */
2269 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002270 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002271 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2272 OMX_COMPONENT_GENERATE_EVENT);
2273 eRet = OMX_ErrorIncorrectStateTransition;
2274 }
2275 /* Requesting transition from Pause to Pause */
2276 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002277 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002278 post_event(OMX_EventError,OMX_ErrorSameState,\
2279 OMX_COMPONENT_GENERATE_EVENT);
2280 eRet = OMX_ErrorSameState;
2281 }
2282 /* Requesting transition from Pause to Invalid */
2283 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002284 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002285 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2286 eRet = OMX_ErrorInvalidState;
2287 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002288 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002289 eRet = OMX_ErrorBadParameter;
2290 }
2291 }
2292 /***************************/
2293 /* Current State is WaitForResources */
2294 /***************************/
2295 else if (m_state == OMX_StateWaitForResources) {
2296 /* Requesting transition from WaitForResources to Loaded */
2297 if (eState == OMX_StateLoaded) {
2298 /* Since error is None , we will post an event
2299 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002300 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002301 }
2302 /* Requesting transition from WaitForResources to WaitForResources */
2303 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002304 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002305 post_event(OMX_EventError,OMX_ErrorSameState,
2306 OMX_COMPONENT_GENERATE_EVENT);
2307 eRet = OMX_ErrorSameState;
2308 }
2309 /* Requesting transition from WaitForResources to Executing */
2310 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002311 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002312 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2313 OMX_COMPONENT_GENERATE_EVENT);
2314 eRet = OMX_ErrorIncorrectStateTransition;
2315 }
2316 /* Requesting transition from WaitForResources to Pause */
2317 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002318 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002319 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2320 OMX_COMPONENT_GENERATE_EVENT);
2321 eRet = OMX_ErrorIncorrectStateTransition;
2322 }
2323 /* Requesting transition from WaitForResources to Invalid */
2324 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002325 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002326 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2327 eRet = OMX_ErrorInvalidState;
2328 }
2329 /* Requesting transition from WaitForResources to Loaded -
2330 is NOT tested by Khronos TS */
2331
2332 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002333 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002334 eRet = OMX_ErrorBadParameter;
2335 }
2336 }
2337 /********************************/
2338 /* Current State is Invalid */
2339 /*******************************/
2340 else if (m_state == OMX_StateInvalid) {
2341 /* State Transition from Inavlid to any state */
2342 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2343 || OMX_StateIdle || OMX_StateExecuting
2344 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002345 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002346 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2347 OMX_COMPONENT_GENERATE_EVENT);
2348 eRet = OMX_ErrorInvalidState;
2349 }
2350 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002351 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002352 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002353#ifdef _MSM8974_
2354 send_codec_config();
2355#endif
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302356 if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
2357 param1 == OMX_ALL)) {
2358 while (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
2359 struct timespec ts;
2360
2361 clock_gettime(CLOCK_REALTIME, &ts);
2362 ts.tv_sec += 2;
2363 DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
2364 m_queued_codec_config_count);
2365 if (sem_timedwait(&m_safe_flush, &ts)) {
2366 DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
2367 break;
2368 }
2369 }
2370 }
2371
Arun Menon906de572013-06-18 17:01:40 -07002372 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2373 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2374 }
2375 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2376 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2377 }
2378 if (!sem_posted) {
2379 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002380 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002381 sem_post (&m_cmd_lock);
2382 execute_omx_flush(param1);
2383 }
2384 bFlag = 0;
2385 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002386 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002387 "with param1: %lu", param1);
2388 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2389 m_inp_bEnabled = OMX_TRUE;
2390
2391 if ( (m_state == OMX_StateLoaded &&
2392 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2393 || allocate_input_done()) {
2394 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2395 OMX_COMPONENT_GENERATE_EVENT);
2396 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002397 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002398 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2399 // Skip the event notification
2400 bFlag = 0;
2401 }
2402 }
2403 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002404 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002405 m_out_bEnabled = OMX_TRUE;
2406
2407 if ( (m_state == OMX_StateLoaded &&
2408 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2409 || (allocate_output_done())) {
2410 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2411 OMX_COMPONENT_GENERATE_EVENT);
2412
2413 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002414 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002415 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2416 // Skip the event notification
2417 bFlag = 0;
2418 }
2419 }
2420 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002421 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002422 "with param1: %lu", param1);
2423 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002424 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002425 m_inp_bEnabled = OMX_FALSE;
2426 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2427 && release_input_done()) {
2428 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2429 OMX_COMPONENT_GENERATE_EVENT);
2430 } else {
2431 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2432 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2433 if (!sem_posted) {
2434 sem_posted = 1;
2435 sem_post (&m_cmd_lock);
2436 }
2437 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2438 }
2439
2440 // Skip the event notification
2441 bFlag = 0;
2442 }
2443 }
2444 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2445 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002446 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002447 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2448 && release_output_done()) {
2449 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2450 OMX_COMPONENT_GENERATE_EVENT);
2451 } else {
2452 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2453 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2454 if (!sem_posted) {
2455 sem_posted = 1;
2456 sem_post (&m_cmd_lock);
2457 }
2458 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2459 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2460 }
2461 // Skip the event notification
2462 bFlag = 0;
2463
2464 }
2465 }
2466 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002467 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002468 eRet = OMX_ErrorNotImplemented;
2469 }
2470 if (eRet == OMX_ErrorNone && bFlag) {
2471 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2472 }
2473 if (!sem_posted) {
2474 sem_post(&m_cmd_lock);
2475 }
2476
2477 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002478}
2479
2480/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002481 FUNCTION
2482 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002483
Arun Menon906de572013-06-18 17:01:40 -07002484 DESCRIPTION
2485 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002486
Arun Menon906de572013-06-18 17:01:40 -07002487 PARAMETERS
2488 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002489
Arun Menon906de572013-06-18 17:01:40 -07002490 RETURN VALUE
2491 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002492
Arun Menon906de572013-06-18 17:01:40 -07002493 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002494bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2495{
Arun Menon906de572013-06-18 17:01:40 -07002496 bool bRet = false;
2497 struct v4l2_plane plane;
2498 struct v4l2_buffer v4l2_buf;
2499 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302500 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002501 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2502 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002503
Arun Menon906de572013-06-18 17:01:40 -07002504 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002505
Arun Menon906de572013-06-18 17:01:40 -07002506 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2507 output_flush_progress = true;
2508 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2509 } else {
2510 /* XXX: The driver/hardware does not support flushing of individual ports
2511 * in all states. So we pretty much need to flush both ports internally,
2512 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2513 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2514 * we automatically omit sending the FLUSH done for the "opposite" port. */
2515 input_flush_progress = true;
2516 output_flush_progress = true;
2517 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2518 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002519
Arun Menon906de572013-06-18 17:01:40 -07002520 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002521 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002522 bRet = false;
2523 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002524
Arun Menon906de572013-06-18 17:01:40 -07002525 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002526}
2527/*=========================================================================
2528FUNCTION : execute_output_flush
2529
2530DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002531Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002532
2533PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002534None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002535
2536RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002537true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002538==========================================================================*/
2539bool omx_vdec::execute_output_flush()
2540{
Arun Menon906de572013-06-18 17:01:40 -07002541 unsigned p1 = 0; // Parameter - 1
2542 unsigned p2 = 0; // Parameter - 2
2543 unsigned ident = 0;
2544 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002545
Arun Menon906de572013-06-18 17:01:40 -07002546 /*Generate FBD for all Buffers in the FTBq*/
2547 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002548 DEBUG_PRINT_LOW("Initiate Output Flush");
vivek mehta79cff222014-01-22 12:17:07 -08002549
2550 //reset last render TS
2551 if(m_last_rendered_TS > 0) {
2552 m_last_rendered_TS = 0;
2553 }
vivek mehtaa75c69f2014-01-10 21:50:37 -08002554
Arun Menon906de572013-06-18 17:01:40 -07002555 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002556 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002557 m_ftb_q.m_size,pending_output_buffers);
2558 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002559 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002560 if (ident == m_fill_output_msg ) {
2561 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2562 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2563 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2564 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002565 }
Arun Menon906de572013-06-18 17:01:40 -07002566 pthread_mutex_unlock(&m_lock);
2567 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002568
Arun Menon906de572013-06-18 17:01:40 -07002569 if (arbitrary_bytes) {
2570 prev_ts = LLONG_MAX;
2571 rst_prev_ts = true;
2572 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002573 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002574 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002575}
2576/*=========================================================================
2577FUNCTION : execute_input_flush
2578
2579DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002580Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002581
2582PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002583None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002584
2585RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002586true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002587==========================================================================*/
2588bool omx_vdec::execute_input_flush()
2589{
Arun Menon906de572013-06-18 17:01:40 -07002590 unsigned i =0;
2591 unsigned p1 = 0; // Parameter - 1
2592 unsigned p2 = 0; // Parameter - 2
2593 unsigned ident = 0;
2594 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002595
Arun Menon906de572013-06-18 17:01:40 -07002596 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002597 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002598
Arun Menon906de572013-06-18 17:01:40 -07002599 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002600 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002601 while (m_etb_q.m_size) {
2602 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002603
Arun Menon906de572013-06-18 17:01:40 -07002604 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002605 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002606 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2607 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2608 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002609 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002610 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2611 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2612 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002613 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002614 (OMX_BUFFERHEADERTYPE *)p1);
2615 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2616 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002617 }
Arun Menon906de572013-06-18 17:01:40 -07002618 time_stamp_dts.flush_timestamp();
2619 /*Check if Heap Buffers are to be flushed*/
2620 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002621 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002622 h264_scratch.nFilledLen = 0;
2623 nal_count = 0;
2624 look_ahead_nal = false;
2625 frame_count = 0;
2626 h264_last_au_ts = LLONG_MAX;
2627 h264_last_au_flags = 0;
2628 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2629 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002630 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002631 if (m_frame_parser.mutils) {
2632 m_frame_parser.mutils->initialize_frame_checking_environment();
2633 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002634
Arun Menon906de572013-06-18 17:01:40 -07002635 while (m_input_pending_q.m_size) {
2636 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2637 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2638 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002639
Arun Menon906de572013-06-18 17:01:40 -07002640 if (psource_frame) {
2641 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2642 psource_frame = NULL;
2643 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002644
Arun Menon906de572013-06-18 17:01:40 -07002645 if (pdest_frame) {
2646 pdest_frame->nFilledLen = 0;
2647 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2648 (unsigned int)NULL);
2649 pdest_frame = NULL;
2650 }
2651 m_frame_parser.flush();
2652 } else if (codec_config_flag) {
2653 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2654 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002655 }
Arun Menon906de572013-06-18 17:01:40 -07002656 pthread_mutex_unlock(&m_lock);
2657 input_flush_progress = false;
2658 if (!arbitrary_bytes) {
2659 prev_ts = LLONG_MAX;
2660 rst_prev_ts = true;
2661 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002662#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002663 if (m_debug_timestamp) {
2664 m_timestamp_list.reset_ts_list();
2665 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002666#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002667 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002668 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002669}
2670
2671
2672/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002673 FUNCTION
2674 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002675
Arun Menon906de572013-06-18 17:01:40 -07002676 DESCRIPTION
2677 Send the event to decoder pipe. This is needed to generate the callbacks
2678 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002679
Arun Menon906de572013-06-18 17:01:40 -07002680 PARAMETERS
2681 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002682
Arun Menon906de572013-06-18 17:01:40 -07002683 RETURN VALUE
2684 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002685
Arun Menon906de572013-06-18 17:01:40 -07002686 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002687bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002688 unsigned int p2,
2689 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002690{
Arun Menon906de572013-06-18 17:01:40 -07002691 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002692
2693
Arun Menon906de572013-06-18 17:01:40 -07002694 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002695
Arun Menon906de572013-06-18 17:01:40 -07002696 if (id == m_fill_output_msg ||
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05302697 id == OMX_COMPONENT_GENERATE_FBD ||
2698 id == OMX_COMPONENT_GENERATE_PORT_RECONFIG) {
Arun Menon906de572013-06-18 17:01:40 -07002699 m_ftb_q.insert_entry(p1,p2,id);
2700 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2701 id == OMX_COMPONENT_GENERATE_EBD ||
2702 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2703 m_etb_q.insert_entry(p1,p2,id);
2704 } else {
2705 m_cmd_q.insert_entry(p1,p2,id);
2706 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002707
Arun Menon906de572013-06-18 17:01:40 -07002708 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002709 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002710 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002711
Arun Menon906de572013-06-18 17:01:40 -07002712 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002713
Arun Menon906de572013-06-18 17:01:40 -07002714 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002715}
2716
2717OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2718{
Arun Menon906de572013-06-18 17:01:40 -07002719 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2720 if (!profileLevelType)
2721 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002722
Arun Menon906de572013-06-18 17:01:40 -07002723 if (profileLevelType->nPortIndex == 0) {
2724 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2725 if (profileLevelType->nProfileIndex == 0) {
2726 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2727 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002728
Arun Menon906de572013-06-18 17:01:40 -07002729 } else if (profileLevelType->nProfileIndex == 1) {
2730 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2731 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2732 } else if (profileLevelType->nProfileIndex == 2) {
2733 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2734 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2735 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002736 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002737 profileLevelType->nProfileIndex);
2738 eRet = OMX_ErrorNoMore;
2739 }
2740 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2741 if (profileLevelType->nProfileIndex == 0) {
2742 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2743 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2744 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002745 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002746 eRet = OMX_ErrorNoMore;
2747 }
2748 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2749 if (profileLevelType->nProfileIndex == 0) {
2750 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2751 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2752 } else if (profileLevelType->nProfileIndex == 1) {
2753 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2754 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2755 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002756 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002757 eRet = OMX_ErrorNoMore;
2758 }
2759 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2760 eRet = OMX_ErrorNoMore;
2761 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2762 if (profileLevelType->nProfileIndex == 0) {
2763 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2764 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2765 } else if (profileLevelType->nProfileIndex == 1) {
2766 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2767 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2768 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002769 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002770 eRet = OMX_ErrorNoMore;
2771 }
2772 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002773 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002774 eRet = OMX_ErrorNoMore;
2775 }
2776 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002777 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002778 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002779 }
Arun Menon906de572013-06-18 17:01:40 -07002780 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002781}
2782
2783/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002784 FUNCTION
2785 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002786
Arun Menon906de572013-06-18 17:01:40 -07002787 DESCRIPTION
2788 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002789
Arun Menon906de572013-06-18 17:01:40 -07002790 PARAMETERS
2791 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002792
Arun Menon906de572013-06-18 17:01:40 -07002793 RETURN VALUE
2794 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002795
Arun Menon906de572013-06-18 17:01:40 -07002796 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002797OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002798 OMX_IN OMX_INDEXTYPE paramIndex,
2799 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002800{
2801 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2802
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002803 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002804 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002805 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002806 return OMX_ErrorInvalidState;
2807 }
Arun Menon906de572013-06-18 17:01:40 -07002808 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002809 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002810 return OMX_ErrorBadParameter;
2811 }
Arun Menon906de572013-06-18 17:01:40 -07002812 switch ((unsigned long)paramIndex) {
2813 case OMX_IndexParamPortDefinition: {
2814 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2815 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002816 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002817 eRet = update_portdef(portDefn);
2818 if (eRet == OMX_ErrorNone)
2819 m_port_def = *portDefn;
2820 break;
2821 }
2822 case OMX_IndexParamVideoInit: {
2823 OMX_PORT_PARAM_TYPE *portParamType =
2824 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002825 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002826
Arun Menon906de572013-06-18 17:01:40 -07002827 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2828 portParamType->nSize = sizeof(portParamType);
2829 portParamType->nPorts = 2;
2830 portParamType->nStartPortNumber = 0;
2831 break;
2832 }
2833 case OMX_IndexParamVideoPortFormat: {
2834 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2835 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002836 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002837
Arun Menon906de572013-06-18 17:01:40 -07002838 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2839 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002840
Arun Menon906de572013-06-18 17:01:40 -07002841 if (0 == portFmt->nPortIndex) {
2842 if (0 == portFmt->nIndex) {
2843 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2844 portFmt->eCompressionFormat = eCompressionFormat;
2845 } else {
2846 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002847 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002848 eRet = OMX_ErrorNoMore;
2849 }
2850 } else if (1 == portFmt->nPortIndex) {
2851 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002852
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07002853 // Distinguish non-surface mode from normal playback use-case based on
2854 // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
2855 // For non-android, use the default list
2856 bool useNonSurfaceMode = false;
2857#if _ANDROID_
2858 useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
2859#endif
2860 portFmt->eColorFormat = useNonSurfaceMode ?
2861 getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
2862 getPreferredColorFormatDefaultMode(portFmt->nIndex);
2863
2864 if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
Praveen Chavandb7776f2014-02-06 18:17:25 -08002865 eRet = OMX_ErrorNoMore;
Arun Menon906de572013-06-18 17:01:40 -07002866 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002867 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002868 }
Praveen Chavandb7776f2014-02-06 18:17:25 -08002869 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002870 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002871 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002872 (int)portFmt->nPortIndex);
2873 eRet = OMX_ErrorBadPortIndex;
2874 }
2875 break;
2876 }
2877 /*Component should support this port definition*/
2878 case OMX_IndexParamAudioInit: {
2879 OMX_PORT_PARAM_TYPE *audioPortParamType =
2880 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002881 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002882 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2883 audioPortParamType->nSize = sizeof(audioPortParamType);
2884 audioPortParamType->nPorts = 0;
2885 audioPortParamType->nStartPortNumber = 0;
2886 break;
2887 }
2888 /*Component should support this port definition*/
2889 case OMX_IndexParamImageInit: {
2890 OMX_PORT_PARAM_TYPE *imagePortParamType =
2891 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002892 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002893 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2894 imagePortParamType->nSize = sizeof(imagePortParamType);
2895 imagePortParamType->nPorts = 0;
2896 imagePortParamType->nStartPortNumber = 0;
2897 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002898
Arun Menon906de572013-06-18 17:01:40 -07002899 }
2900 /*Component should support this port definition*/
2901 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002902 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002903 paramIndex);
2904 eRet =OMX_ErrorUnsupportedIndex;
2905 break;
2906 }
2907 case OMX_IndexParamStandardComponentRole: {
2908 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2909 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2910 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2911 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002912
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002913 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002914 paramIndex);
2915 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2916 OMX_MAX_STRINGNAME_SIZE);
2917 break;
2918 }
2919 /* Added for parameter test */
2920 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002921
Arun Menon906de572013-06-18 17:01:40 -07002922 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2923 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002924 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002925 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2926 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002927
Arun Menon906de572013-06-18 17:01:40 -07002928 break;
2929 }
2930 /* Added for parameter test */
2931 case OMX_IndexParamCompBufferSupplier: {
2932 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2933 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002934 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002935
Arun Menon906de572013-06-18 17:01:40 -07002936 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2937 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2938 if (0 == bufferSupplierType->nPortIndex)
2939 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2940 else if (1 == bufferSupplierType->nPortIndex)
2941 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2942 else
2943 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002944
2945
Arun Menon906de572013-06-18 17:01:40 -07002946 break;
2947 }
2948 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002949 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002950 paramIndex);
2951 break;
2952 }
2953 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002954 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002955 paramIndex);
2956 break;
2957 }
2958 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002959 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002960 paramIndex);
2961 break;
2962 }
2963 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002964 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002965 paramIndex);
2966 break;
2967 }
2968 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002969 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002970 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2971 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2972 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2973 break;
2974 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002975#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002976 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002977 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002978 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2979 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002980
Arun Menon906de572013-06-18 17:01:40 -07002981 if (secure_mode) {
2982 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2983 GRALLOC_USAGE_PRIVATE_UNCACHED);
2984 } else {
2985 nativeBuffersUsage->nUsage =
2986 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2987 GRALLOC_USAGE_PRIVATE_UNCACHED);
2988 }
2989 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002990 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002991 eRet = OMX_ErrorBadParameter;
2992 }
2993 }
2994 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002995#endif
2996
Deva Ramasubramanian286a3582014-08-25 18:09:38 -07002997 case OMX_QcomIndexParamVideoProcessNotCodedVOP:
2998 {
2999 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoProcessNotCodedVOP");
3000 ((QOMX_ENABLETYPE *)paramData)->bEnable = (OMX_BOOL)!ignore_not_coded_vops;
3001 break;
3002 }
Arun Menon906de572013-06-18 17:01:40 -07003003 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003004 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003005 eRet =OMX_ErrorUnsupportedIndex;
3006 }
3007
Shalaj Jain273b3e02012-06-22 19:08:03 -07003008 }
3009
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003010 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07003011 drv_ctx.video_resolution.frame_width,
3012 drv_ctx.video_resolution.frame_height,
3013 drv_ctx.video_resolution.stride,
3014 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003015
Arun Menon906de572013-06-18 17:01:40 -07003016 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003017}
3018
3019#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3020OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
3021{
3022 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
3023 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3024 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
3025
Arun Menon906de572013-06-18 17:01:40 -07003026 if ((params == NULL) ||
3027 (params->nativeBuffer == NULL) ||
3028 (params->nativeBuffer->handle == NULL) ||
3029 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003030 return OMX_ErrorBadParameter;
3031 m_use_android_native_buffers = OMX_TRUE;
3032 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3033 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07003034 if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
Shalaj Jain273b3e02012-06-22 19:08:03 -07003035 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07003036 if (!secure_mode) {
3037 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003038 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07003039 if (buffer == MAP_FAILED) {
3040 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3041 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003042 }
3043 }
3044 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3045 } else {
3046 eRet = OMX_ErrorBadParameter;
3047 }
3048 return eRet;
3049}
3050#endif
Praveen Chavancf924182013-12-06 23:16:23 -08003051
3052OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
3053 struct v4l2_control control;
3054 struct v4l2_format fmt;
3055 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3056 control.value = 1;
3057 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3058 if (rc < 0) {
3059 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3060 return OMX_ErrorHardware;
3061 }
3062 m_smoothstreaming_mode = true;
3063 return OMX_ErrorNone;
3064}
3065
Shalaj Jain273b3e02012-06-22 19:08:03 -07003066/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003067 FUNCTION
3068 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07003069
Arun Menon906de572013-06-18 17:01:40 -07003070 DESCRIPTION
3071 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003072
Arun Menon906de572013-06-18 17:01:40 -07003073 PARAMETERS
3074 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003075
Arun Menon906de572013-06-18 17:01:40 -07003076 RETURN VALUE
3077 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003078
Arun Menon906de572013-06-18 17:01:40 -07003079 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003080OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003081 OMX_IN OMX_INDEXTYPE paramIndex,
3082 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003083{
3084 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003085 int ret=0;
3086 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07003087 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003088 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003089 return OMX_ErrorInvalidState;
3090 }
Arun Menon906de572013-06-18 17:01:40 -07003091 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003092 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07003093 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003094 }
Arun Menon906de572013-06-18 17:01:40 -07003095 if ((m_state != OMX_StateLoaded) &&
3096 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3097 (m_out_bEnabled == OMX_TRUE) &&
3098 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3099 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003100 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003101 return OMX_ErrorIncorrectStateOperation;
3102 }
Arun Menon906de572013-06-18 17:01:40 -07003103 switch ((unsigned long)paramIndex) {
3104 case OMX_IndexParamPortDefinition: {
3105 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3106 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3107 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3108 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003109 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07003110 (int)portDefn->format.video.nFrameHeight,
3111 (int)portDefn->format.video.nFrameWidth);
3112 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003113 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Pushkaraj Patil41588352014-02-25 20:51:34 +05303114 bool port_format_changed = false;
Arun Menon906de572013-06-18 17:01:40 -07003115 m_display_id = portDefn->format.video.pNativeWindow;
3116 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08003117 /* update output port resolution with client supplied dimensions
3118 in case scaling is enabled, else it follows input resolution set
3119 */
3120 if (is_down_scalar_enabled) {
3121 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003122 portDefn->format.video.nFrameWidth,
3123 portDefn->format.video.nFrameHeight);
3124 if (portDefn->format.video.nFrameHeight != 0x0 &&
3125 portDefn->format.video.nFrameWidth != 0x0) {
Pushkaraj Patil41588352014-02-25 20:51:34 +05303126 memset(&fmt, 0x0, sizeof(struct v4l2_format));
3127 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3128 fmt.fmt.pix_mp.pixelformat = capture_capability;
3129 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
3130 if (ret) {
3131 DEBUG_PRINT_ERROR("Get Resolution failed");
3132 eRet = OMX_ErrorHardware;
3133 break;
3134 }
3135 if ((portDefn->format.video.nFrameHeight != (int)fmt.fmt.pix_mp.height) ||
3136 (portDefn->format.video.nFrameWidth != (int)fmt.fmt.pix_mp.width)) {
3137 port_format_changed = true;
3138 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003139 update_resolution(portDefn->format.video.nFrameWidth,
3140 portDefn->format.video.nFrameHeight,
3141 portDefn->format.video.nFrameWidth,
3142 portDefn->format.video.nFrameHeight);
Pushkaraj Patil41588352014-02-25 20:51:34 +05303143
3144 /* set crop info */
3145 rectangle.nLeft = 0;
3146 rectangle.nTop = 0;
3147 rectangle.nWidth = portDefn->format.video.nFrameWidth;
3148 rectangle.nHeight = portDefn->format.video.nFrameHeight;
3149
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003150 eRet = is_video_session_supported();
3151 if (eRet)
3152 break;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303153 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003154 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3155 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3156 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3157 fmt.fmt.pix_mp.pixelformat = capture_capability;
3158 DEBUG_PRINT_LOW("\n fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d \n",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
3159 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3160 if (ret) {
3161 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3162 eRet = OMX_ErrorUnsupportedSetting;
3163 } else
3164 eRet = get_buffer_req(&drv_ctx.op_buf);
3165 }
Praveen Chavane78460c2013-12-06 23:16:04 -08003166 }
Arun Menon906de572013-06-18 17:01:40 -07003167 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003168 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07003169 eRet = OMX_ErrorBadParameter;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303170 } else if (!port_format_changed) {
Arun Menon906de572013-06-18 17:01:40 -07003171 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3172 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
3173 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3174 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3175 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
3176 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
3177 drv_ctx.extradata_info.buffer_size;
3178 eRet = set_buffer_req(&drv_ctx.op_buf);
3179 if (eRet == OMX_ErrorNone)
3180 m_port_def = *portDefn;
3181 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003182 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003183 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3184 portDefn->nBufferCountActual, portDefn->nBufferSize);
3185 eRet = OMX_ErrorBadParameter;
3186 }
3187 }
3188 } else if (OMX_DirInput == portDefn->eDir) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003189 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003190 bool port_format_changed = false;
3191 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
3192 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
3193 // Frame rate only should be set if this is a "known value" or to
3194 // activate ts prediction logic (arbitrary mode only) sending input
3195 // timestamps with max value (LLONG_MAX).
3196 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
3197 portDefn->format.video.xFramerate >> 16);
3198 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3199 drv_ctx.frame_rate.fps_denominator);
3200 if (!drv_ctx.frame_rate.fps_numerator) {
3201 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3202 drv_ctx.frame_rate.fps_numerator = 30;
3203 }
3204 if (drv_ctx.frame_rate.fps_denominator)
3205 drv_ctx.frame_rate.fps_numerator = (int)
3206 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3207 drv_ctx.frame_rate.fps_denominator = 1;
3208 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3209 drv_ctx.frame_rate.fps_numerator;
3210 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3211 frm_int, drv_ctx.frame_rate.fps_numerator /
3212 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003213
3214 struct v4l2_outputparm oparm;
3215 /*XXX: we're providing timing info as seconds per frame rather than frames
3216 * per second.*/
3217 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3218 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3219
3220 struct v4l2_streamparm sparm;
3221 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3222 sparm.parm.output = oparm;
3223 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3224 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
3225 eRet = OMX_ErrorHardware;
3226 break;
3227 }
Arun Menon906de572013-06-18 17:01:40 -07003228 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003229
Arun Menon906de572013-06-18 17:01:40 -07003230 if (drv_ctx.video_resolution.frame_height !=
3231 portDefn->format.video.nFrameHeight ||
3232 drv_ctx.video_resolution.frame_width !=
3233 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003234 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003235 portDefn->format.video.nFrameWidth,
3236 portDefn->format.video.nFrameHeight);
3237 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003238 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3239 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3240 if (frameHeight != 0x0 && frameWidth != 0x0) {
3241 if (m_smoothstreaming_mode &&
3242 ((frameWidth * frameHeight) <
3243 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3244 frameWidth = m_smoothstreaming_width;
3245 frameHeight = m_smoothstreaming_height;
3246 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3247 frameWidth, frameHeight);
3248 }
3249 update_resolution(frameWidth, frameHeight,
3250 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003251 eRet = is_video_session_supported();
3252 if (eRet)
3253 break;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303254 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Arun Menon906de572013-06-18 17:01:40 -07003255 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3256 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3257 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3258 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003259 DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
Arun Menon906de572013-06-18 17:01:40 -07003260 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3261 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003262 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003263 eRet = OMX_ErrorUnsupportedSetting;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303264 } else {
3265 if (!is_down_scalar_enabled)
3266 eRet = get_buffer_req(&drv_ctx.op_buf);
3267 }
Arun Menon906de572013-06-18 17:01:40 -07003268 }
3269 }
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +05303270 if (m_custom_buffersize.input_buffersize
3271 && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
3272 DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
3273 m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
3274 eRet = OMX_ErrorBadParameter;
3275 break;
3276 }
Arun Menon906de572013-06-18 17:01:40 -07003277 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3278 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3279 port_format_changed = true;
3280 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3281 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3282 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3283 (~(buffer_prop->alignment - 1));
3284 eRet = set_buffer_req(buffer_prop);
3285 }
3286 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003287 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003288 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3289 portDefn->nBufferCountActual, portDefn->nBufferSize);
3290 eRet = OMX_ErrorBadParameter;
3291 }
3292 } else if (portDefn->eDir == OMX_DirMax) {
3293 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3294 (int)portDefn->nPortIndex);
3295 eRet = OMX_ErrorBadPortIndex;
3296 }
3297 }
3298 break;
3299 case OMX_IndexParamVideoPortFormat: {
3300 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3301 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3302 int ret=0;
3303 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003304 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003305 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003306
Arun Menon906de572013-06-18 17:01:40 -07003307 if (1 == portFmt->nPortIndex) {
3308 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3309 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3310 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3311 fmt.fmt.pix_mp.pixelformat = capture_capability;
3312 enum vdec_output_fromat op_format;
3313 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3314 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Praveen Chavandb7776f2014-02-06 18:17:25 -08003315 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
3316 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar))
Arun Menon906de572013-06-18 17:01:40 -07003317 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Arun Menon906de572013-06-18 17:01:40 -07003318 else
3319 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003320
Arun Menon906de572013-06-18 17:01:40 -07003321 if (eRet == OMX_ErrorNone) {
3322 drv_ctx.output_format = op_format;
3323 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3324 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003325 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003326 eRet = OMX_ErrorUnsupportedSetting;
3327 /*TODO: How to handle this case */
3328 } else {
3329 eRet = get_buffer_req(&drv_ctx.op_buf);
3330 }
3331 }
3332 if (eRet == OMX_ErrorNone) {
3333 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003334 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003335 eRet = OMX_ErrorBadParameter;
3336 }
3337 }
3338 }
3339 }
3340 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003341
Arun Menon906de572013-06-18 17:01:40 -07003342 case OMX_QcomIndexPortDefn: {
3343 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3344 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003345 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003346 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003347
Arun Menon906de572013-06-18 17:01:40 -07003348 /* Input port */
3349 if (portFmt->nPortIndex == 0) {
3350 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3351 if (secure_mode) {
3352 arbitrary_bytes = false;
3353 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3354 eRet = OMX_ErrorUnsupportedSetting;
3355 } else {
3356 arbitrary_bytes = true;
3357 }
3358 } else if (portFmt->nFramePackingFormat ==
3359 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3360 arbitrary_bytes = false;
3361 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003362 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003363 portFmt->nFramePackingFormat);
3364 eRet = OMX_ErrorUnsupportedSetting;
3365 }
3366 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003367 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003368 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3369 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3370 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3371 m_out_mem_region_smi = OMX_TRUE;
3372 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003373 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003374 m_use_output_pmem = OMX_TRUE;
3375 }
3376 }
3377 }
3378 }
3379 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003380
Arun Menon906de572013-06-18 17:01:40 -07003381 case OMX_IndexParamStandardComponentRole: {
3382 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3383 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003384 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003385 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003386
Arun Menon906de572013-06-18 17:01:40 -07003387 if ((m_state == OMX_StateLoaded)&&
3388 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3389 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3390 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003391 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003392 return OMX_ErrorIncorrectStateOperation;
3393 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003394
Arun Menon906de572013-06-18 17:01:40 -07003395 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3396 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3397 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3398 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003399 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003400 eRet =OMX_ErrorUnsupportedSetting;
3401 }
3402 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3403 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3404 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3405 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003406 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003407 eRet = OMX_ErrorUnsupportedSetting;
3408 }
3409 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3410 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3411 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3412 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003413 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003414 eRet =OMX_ErrorUnsupportedSetting;
3415 }
3416 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3417 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3418 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3419 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003420 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003421 eRet = OMX_ErrorUnsupportedSetting;
3422 }
3423 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
Deva Ramasubramanianba4534b2013-12-17 15:52:37 -08003424 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) ||
3425 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE))
Arun Menon906de572013-06-18 17:01:40 -07003426 ) {
3427 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3428 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3429 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003430 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003431 eRet =OMX_ErrorUnsupportedSetting;
3432 }
3433 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3434 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3435 ) {
3436 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3437 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3438 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003439 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003440 eRet =OMX_ErrorUnsupportedSetting;
3441 }
3442 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3443 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3444 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3445 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3446 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003447 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003448 eRet = OMX_ErrorUnsupportedSetting;
3449 }
3450 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003451 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003452 eRet = OMX_ErrorInvalidComponentName;
3453 }
3454 break;
3455 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003456
Arun Menon906de572013-06-18 17:01:40 -07003457 case OMX_IndexParamPriorityMgmt: {
3458 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003459 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003460 return OMX_ErrorIncorrectStateOperation;
3461 }
3462 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003463 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003464 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003465
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003466 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003467 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003468
Arun Menon906de572013-06-18 17:01:40 -07003469 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3470 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003471
Arun Menon906de572013-06-18 17:01:40 -07003472 break;
3473 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003474
Arun Menon906de572013-06-18 17:01:40 -07003475 case OMX_IndexParamCompBufferSupplier: {
3476 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003477 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003478 bufferSupplierType->eBufferSupplier);
3479 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3480 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003481
Arun Menon906de572013-06-18 17:01:40 -07003482 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003483
Arun Menon906de572013-06-18 17:01:40 -07003484 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003485
Arun Menon906de572013-06-18 17:01:40 -07003486 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003487
Arun Menon906de572013-06-18 17:01:40 -07003488 }
3489 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003490 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003491 paramIndex);
3492 break;
3493 }
3494 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003495 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003496 paramIndex);
3497 break;
3498 }
3499 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003500 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003501 paramIndex);
3502 break;
3503 }
3504 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003505 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003506 paramIndex);
3507 break;
3508 }
3509 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3510 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3511 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3512 struct v4l2_control control;
3513 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003514 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003515 pictureOrder->eOutputPictureOrder);
3516 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3517 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3518 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3519 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3520 time_stamp_dts.set_timestamp_reorder_mode(false);
3521 } else
3522 eRet = OMX_ErrorBadParameter;
3523 if (eRet == OMX_ErrorNone) {
3524 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3525 control.value = pic_order;
3526 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3527 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003528 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003529 eRet = OMX_ErrorUnsupportedSetting;
3530 }
3531 }
3532 break;
3533 }
3534 case OMX_QcomIndexParamConcealMBMapExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303535 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3536 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3537 break;
3538 case OMX_QcomIndexParamFrameInfoExtraData:
3539 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3540 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3541 break;
Arun Menon906de572013-06-18 17:01:40 -07003542 case OMX_QcomIndexParamInterlaceExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303543 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3544 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3545 break;
Arun Menon906de572013-06-18 17:01:40 -07003546 case OMX_QcomIndexParamH264TimeInfo:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303547 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3548 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3549 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303550 case OMX_QcomIndexParamVideoFramePackingExtradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303551 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3552 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3553 break;
3554 case OMX_QcomIndexParamVideoQPExtraData:
3555 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
3556 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3557 break;
3558 case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
3559 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
3560 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3561 break;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05303562 case OMX_QcomIndexEnableExtnUserData:
3563 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
3564 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3565 break;
Arun Menon906de572013-06-18 17:01:40 -07003566 case OMX_QcomIndexParamVideoDivx: {
3567 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3568 }
3569 break;
3570 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003571 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003572 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3573 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3574 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3575 eRet = OMX_ErrorUnsupportedSetting;
3576 } else {
3577 m_out_pvt_entry_pmem = OMX_TRUE;
3578 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003579 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003580 m_use_output_pmem = OMX_TRUE;
3581 }
3582 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003583
Arun Menon906de572013-06-18 17:01:40 -07003584 }
3585 break;
3586 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3587 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3588 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3589 struct v4l2_control control;
3590 int rc;
3591 drv_ctx.idr_only_decoding = 1;
3592 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3593 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3594 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3595 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003596 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003597 eRet = OMX_ErrorUnsupportedSetting;
3598 } else {
3599 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3600 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3601 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3602 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003603 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003604 eRet = OMX_ErrorUnsupportedSetting;
3605 }
3606 /*Setting sync frame decoding on driver might change buffer
3607 * requirements so update them here*/
3608 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003609 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003610 eRet = OMX_ErrorUnsupportedSetting;
3611 }
3612 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003613 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003614 eRet = OMX_ErrorUnsupportedSetting;
3615 }
3616 }
3617 }
3618 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003619
Arun Menon906de572013-06-18 17:01:40 -07003620 case OMX_QcomIndexParamIndexExtraDataType: {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303621 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3622 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3623 (extradataIndexType->bEnabled == OMX_TRUE) &&
3624 (extradataIndexType->nPortIndex == 1)) {
3625 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
3626 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
3627 }
3628 }
Arun Menon906de572013-06-18 17:01:40 -07003629 break;
3630 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003631#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003632 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003633#else
Arun Menon906de572013-06-18 17:01:40 -07003634 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003635#endif
Arun Menon906de572013-06-18 17:01:40 -07003636 }
3637 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003638#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003639 /* Need to allow following two set_parameters even in Idle
3640 * state. This is ANDROID architecture which is not in sync
3641 * with openmax standard. */
3642 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3643 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3644 if (enableNativeBuffers) {
3645 m_enable_android_native_buffers = enableNativeBuffers->enable;
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07003646 }
3647 if (m_enable_android_native_buffers) {
3648 // Use the most-preferred-native-color-format as surface-mode is hinted here
3649 if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
3650 DEBUG_PRINT_ERROR("Failed to set native color format!");
3651 eRet = OMX_ErrorUnsupportedSetting;
3652 }
Arun Menon906de572013-06-18 17:01:40 -07003653 }
3654 }
3655 break;
3656 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3657 eRet = use_android_native_buffer(hComp, paramData);
3658 }
3659 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003660#endif
Arun Menon906de572013-06-18 17:01:40 -07003661 case OMX_QcomIndexParamEnableTimeStampReorder: {
3662 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3663 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3664 if (reorder->bEnable == OMX_TRUE) {
3665 frm_int =0;
3666 time_stamp_dts.set_timestamp_reorder_mode(true);
3667 } else
3668 time_stamp_dts.set_timestamp_reorder_mode(false);
3669 } else {
3670 time_stamp_dts.set_timestamp_reorder_mode(false);
3671 if (reorder->bEnable == OMX_TRUE) {
3672 eRet = OMX_ErrorUnsupportedSetting;
3673 }
3674 }
3675 }
3676 break;
3677 case OMX_IndexParamVideoProfileLevelCurrent: {
3678 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3679 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3680 if (pParam) {
3681 m_profile_lvl.eProfile = pParam->eProfile;
3682 m_profile_lvl.eLevel = pParam->eLevel;
3683 }
3684 break;
Arun Menon888aa852013-05-30 11:24:42 -07003685
Arun Menon906de572013-06-18 17:01:40 -07003686 }
Arun Menone5652482013-08-04 13:33:05 -07003687 case OMX_QcomIndexParamVideoMetaBufferMode:
3688 {
3689 StoreMetaDataInBuffersParams *metabuffer =
3690 (StoreMetaDataInBuffersParams *)paramData;
3691 if (!metabuffer) {
3692 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3693 eRet = OMX_ErrorBadParameter;
3694 break;
3695 }
3696 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3697 //set property dynamic buffer mode to driver.
3698 struct v4l2_control control;
3699 struct v4l2_format fmt;
3700 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3701 if (metabuffer->bStoreMetaData == true) {
3702 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3703 } else {
3704 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3705 }
3706 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3707 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003708 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003709 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003710 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003711 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003712 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003713 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3714 eRet = OMX_ErrorUnsupportedSetting;
3715 }
3716 } else {
3717 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003718 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003719 metabuffer->nPortIndex);
3720 eRet = OMX_ErrorUnsupportedSetting;
3721 }
3722 break;
3723 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003724 case OMX_QcomIndexParamVideoDownScalar: {
3725 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3726 struct v4l2_control control;
3727 int rc;
3728 if (pParam) {
3729 is_down_scalar_enabled = pParam->bEnable;
3730 if (is_down_scalar_enabled) {
3731 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3732 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3733 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3734 pParam->bEnable);
3735 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3736 if (rc < 0) {
3737 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3738 eRet = OMX_ErrorUnsupportedSetting;
3739 }
3740 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3741 control.value = 1;
3742 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3743 if (rc < 0) {
3744 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3745 eRet = OMX_ErrorUnsupportedSetting;
3746 }
3747 }
3748 }
3749 break;
3750 }
Praveen Chavancf924182013-12-06 23:16:23 -08003751#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3752 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3753 {
3754 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3755 PrepareForAdaptivePlaybackParams* pParams =
3756 (PrepareForAdaptivePlaybackParams *) paramData;
3757 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3758 if (!pParams->bEnable) {
3759 return OMX_ErrorNone;
3760 }
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303761 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
3762 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
Praveen Chavancf924182013-12-06 23:16:23 -08003763 DEBUG_PRINT_ERROR(
3764 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3765 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303766 maxSmoothStreamingWidth, maxSmoothStreamingHeight);
Praveen Chavancf924182013-12-06 23:16:23 -08003767 eRet = OMX_ErrorBadParameter;
3768 } else {
Arun Menon1fc764f2014-04-17 15:41:27 -07003769 eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3770 }
Praveen Chavancf924182013-12-06 23:16:23 -08003771 } else {
3772 DEBUG_PRINT_ERROR(
3773 "Prepare for adaptive playback supported only on output port");
3774 eRet = OMX_ErrorBadParameter;
3775 }
3776 break;
3777 }
3778
3779#endif
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +05303780 case OMX_QcomIndexParamVideoCustomBufferSize:
3781 {
3782 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
3783 QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
3784 if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3785 struct v4l2_control control;
3786 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
3787 control.value = pParam->nBufferSize;
3788 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
3789 DEBUG_PRINT_ERROR("Failed to set input buffer size");
3790 eRet = OMX_ErrorUnsupportedSetting;
3791 } else {
3792 eRet = get_buffer_req(&drv_ctx.ip_buf);
3793 if (eRet == OMX_ErrorNone) {
3794 m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
3795 DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
3796 m_custom_buffersize.input_buffersize);
3797 } else {
3798 DEBUG_PRINT_ERROR("Failed to get buffer requirement");
3799 }
3800 }
3801 } else {
3802 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
3803 eRet = OMX_ErrorBadParameter;
3804 }
3805 break;
3806 }
Deva Ramasubramanian286a3582014-08-25 18:09:38 -07003807 case OMX_QcomIndexParamVideoProcessNotCodedVOP:
3808 {
3809 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoProcessNotCodedVOP");
3810 ignore_not_coded_vops = !((QOMX_ENABLETYPE *)paramData)->bEnable;
3811 break;
3812 }
Arun Menon906de572013-06-18 17:01:40 -07003813 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003814 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003815 eRet = OMX_ErrorUnsupportedIndex;
3816 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003817 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003818 if (eRet != OMX_ErrorNone)
3819 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003820 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003821}
3822
3823/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003824 FUNCTION
3825 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003826
Arun Menon906de572013-06-18 17:01:40 -07003827 DESCRIPTION
3828 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003829
Arun Menon906de572013-06-18 17:01:40 -07003830 PARAMETERS
3831 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003832
Arun Menon906de572013-06-18 17:01:40 -07003833 RETURN VALUE
3834 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003835
Arun Menon906de572013-06-18 17:01:40 -07003836 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003837OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003838 OMX_IN OMX_INDEXTYPE configIndex,
3839 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003840{
Arun Menon906de572013-06-18 17:01:40 -07003841 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003842
Arun Menon906de572013-06-18 17:01:40 -07003843 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003844 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003845 return OMX_ErrorInvalidState;
3846 }
Arun Menon906de572013-06-18 17:01:40 -07003847
3848 switch ((unsigned long)configIndex) {
3849 case OMX_QcomIndexConfigInterlaced: {
3850 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3851 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3852 if (configFmt->nPortIndex == 1) {
3853 if (configFmt->nIndex == 0) {
3854 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3855 } else if (configFmt->nIndex == 1) {
3856 configFmt->eInterlaceType =
3857 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3858 } else if (configFmt->nIndex == 2) {
3859 configFmt->eInterlaceType =
3860 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3861 } else {
3862 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003863 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003864 eRet = OMX_ErrorNoMore;
3865 }
3866
3867 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003868 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003869 (int)configFmt->nPortIndex);
3870 eRet = OMX_ErrorBadPortIndex;
3871 }
3872 break;
3873 }
3874 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3875 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3876 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3877 decoderinstances->nNumOfInstances = 16;
3878 /*TODO: How to handle this case */
3879 break;
3880 }
3881 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3882 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3883 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3884 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303885 memcpy(configFmt, &m_frame_pack_arrangement,
3886 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003887 } else {
3888 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3889 }
3890 break;
3891 }
3892 case OMX_IndexConfigCommonOutputCrop: {
3893 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3894 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05303895 DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
3896 rectangle.nLeft, rectangle.nTop,
3897 rectangle.nWidth, rectangle.nHeight);
Arun Menon906de572013-06-18 17:01:40 -07003898 break;
3899 }
3900 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003901 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003902 eRet = OMX_ErrorBadParameter;
3903 }
3904
Shalaj Jain273b3e02012-06-22 19:08:03 -07003905 }
Arun Menon906de572013-06-18 17:01:40 -07003906
3907 return eRet;
3908}
3909
3910/* ======================================================================
3911 FUNCTION
3912 omx_vdec::SetConfig
3913
3914 DESCRIPTION
3915 OMX Set Config method implementation
3916
3917 PARAMETERS
3918 <TBD>.
3919
3920 RETURN VALUE
3921 OMX Error None if successful.
3922 ========================================================================== */
3923OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3924 OMX_IN OMX_INDEXTYPE configIndex,
3925 OMX_IN OMX_PTR configData)
3926{
3927 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003928 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003929 return OMX_ErrorInvalidState;
3930 }
3931
3932 OMX_ERRORTYPE ret = OMX_ErrorNone;
3933 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3934
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003935 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003936
3937 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3938 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003939 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003940 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003941 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003942 OMX_U32 extra_size;
3943 // Parsing done here for the AVC atom is definitely not generic
3944 // Currently this piece of code is working, but certainly
3945 // not tested with all .mp4 files.
3946 // Incase of failure, we might need to revisit this
3947 // for a generic piece of code.
3948
3949 // Retrieve size of NAL length field
3950 // byte #4 contains the size of NAL lenght field
3951 nal_length = (config->pData[4] & 0x03) + 1;
3952
3953 extra_size = 0;
3954 if (nal_length > 2) {
3955 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3956 extra_size = (nal_length - 2) * 2;
3957 }
3958
3959 // SPS starts from byte #6
3960 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3961 OMX_U8 *pDestBuf;
3962 m_vendor_config.nPortIndex = config->nPortIndex;
3963
3964 // minus 6 --> SPS starts from byte #6
3965 // minus 1 --> picture param set byte to be ignored from avcatom
3966 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3967 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3968 OMX_U32 len;
3969 OMX_U8 index = 0;
3970 // case where SPS+PPS is sent as part of set_config
3971 pDestBuf = m_vendor_config.pData;
3972
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003973 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003974 m_vendor_config.nPortIndex,
3975 m_vendor_config.nDataSize,
3976 m_vendor_config.pData);
3977 while (index < 2) {
3978 uint8 *psize;
3979 len = *pSrcBuf;
3980 len = len << 8;
3981 len |= *(pSrcBuf + 1);
3982 psize = (uint8 *) & len;
3983 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3984 for (unsigned int i = 0; i < nal_length; i++) {
3985 pDestBuf[i] = psize[nal_length - 1 - i];
3986 }
3987 //memcpy(pDestBuf,pSrcBuf,(len+2));
3988 pDestBuf += len + nal_length;
3989 pSrcBuf += len + 2;
3990 index++;
3991 pSrcBuf++; // skip picture param set
3992 len = 0;
3993 }
3994 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3995 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3996 m_vendor_config.nPortIndex = config->nPortIndex;
3997 m_vendor_config.nDataSize = config->nDataSize;
3998 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3999 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
4000 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
4001 if (m_vendor_config.pData) {
4002 free(m_vendor_config.pData);
4003 m_vendor_config.pData = NULL;
4004 m_vendor_config.nDataSize = 0;
4005 }
4006
4007 if (((*((OMX_U32 *) config->pData)) &
4008 VC1_SP_MP_START_CODE_MASK) ==
4009 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004010 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07004011 m_vendor_config.nPortIndex = config->nPortIndex;
4012 m_vendor_config.nDataSize = config->nDataSize;
4013 m_vendor_config.pData =
4014 (OMX_U8 *) malloc(config->nDataSize);
4015 memcpy(m_vendor_config.pData, config->pData,
4016 config->nDataSize);
4017 m_vc1_profile = VC1_SP_MP_RCV;
4018 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004019 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07004020 m_vendor_config.nPortIndex = config->nPortIndex;
4021 m_vendor_config.nDataSize = config->nDataSize;
4022 m_vendor_config.pData =
4023 (OMX_U8 *) malloc((config->nDataSize));
4024 memcpy(m_vendor_config.pData, config->pData,
4025 config->nDataSize);
4026 m_vc1_profile = VC1_AP;
4027 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004028 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07004029 m_vendor_config.nPortIndex = config->nPortIndex;
4030 m_vendor_config.nDataSize = config->nDataSize;
4031 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
4032 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
4033 m_vc1_profile = VC1_SP_MP_RCV;
4034 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004035 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07004036 }
4037 }
4038 return ret;
4039 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
4040 struct v4l2_control temp;
4041 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
4042
4043 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
4044 switch (pNal->nNaluBytes) {
4045 case 0:
4046 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
4047 break;
4048 case 2:
4049 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
4050 break;
4051 case 4:
4052 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
4053 break;
4054 default:
4055 return OMX_ErrorUnsupportedSetting;
4056 }
4057
4058 if (!arbitrary_bytes) {
4059 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
4060 * with start code, so only need to notify driver in frame by frame mode */
4061 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
4062 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
4063 return OMX_ErrorHardware;
4064 }
4065 }
4066
4067 nal_length = pNal->nNaluBytes;
4068 m_frame_parser.init_nal_length(nal_length);
4069
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004070 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07004071 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05304072 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07004073 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05304074 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07004075
4076 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
4077 if (config->bEnabled) {
4078 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05304079 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07004080 config->nFps >> 16);
4081 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
4082 drv_ctx.frame_rate.fps_denominator);
4083
4084 if (!drv_ctx.frame_rate.fps_numerator) {
4085 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
4086 drv_ctx.frame_rate.fps_numerator = 30;
4087 }
4088
4089 if (drv_ctx.frame_rate.fps_denominator) {
4090 drv_ctx.frame_rate.fps_numerator = (int)
4091 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
4092 }
4093
4094 drv_ctx.frame_rate.fps_denominator = 1;
4095 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
4096 drv_ctx.frame_rate.fps_numerator;
4097
4098 struct v4l2_outputparm oparm;
4099 /*XXX: we're providing timing info as seconds per frame rather than frames
4100 * per second.*/
4101 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
4102 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
4103
4104 struct v4l2_streamparm sparm;
4105 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4106 sparm.parm.output = oparm;
4107 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
4108 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
4109 performance might be affected");
4110 ret = OMX_ErrorHardware;
4111 }
4112 client_set_fps = true;
4113 } else {
4114 DEBUG_PRINT_ERROR("Frame rate not supported.");
4115 ret = OMX_ErrorUnsupportedSetting;
4116 }
4117 } else {
4118 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
4119 client_set_fps = false;
4120 }
4121 } else {
4122 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
4123 (int)config->nPortIndex);
4124 ret = OMX_ErrorBadPortIndex;
4125 }
4126
4127 return ret;
4128 }
4129
4130 return OMX_ErrorNotImplemented;
4131}
4132
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304133#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
4134
Arun Menon906de572013-06-18 17:01:40 -07004135/* ======================================================================
4136 FUNCTION
4137 omx_vdec::GetExtensionIndex
4138
4139 DESCRIPTION
4140 OMX GetExtensionIndex method implementaion. <TBD>
4141
4142 PARAMETERS
4143 <TBD>.
4144
4145 RETURN VALUE
4146 OMX Error None if everything successful.
4147
4148 ========================================================================== */
4149OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
4150 OMX_IN OMX_STRING paramName,
4151 OMX_OUT OMX_INDEXTYPE* indexType)
4152{
4153 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004154 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004155 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304156 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07004157 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304158 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004159 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304160 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
4161 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
4162 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
4163 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08004164 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
4165 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08004166 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
4167 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08004168 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
4169 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004170 }
4171#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304172 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004173 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304174 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004175 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304176 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004177 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004178 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304179 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004180 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4181 }
4182#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304183 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07004184 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
4185 }
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05304186#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Praveen Chavancf924182013-12-06 23:16:23 -08004187 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
4188 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
4189 }
4190#endif
Arun Menon906de572013-06-18 17:01:40 -07004191 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004192 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004193 return OMX_ErrorNotImplemented;
4194 }
4195 return OMX_ErrorNone;
4196}
4197
4198/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004199 FUNCTION
4200 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07004201
Arun Menon906de572013-06-18 17:01:40 -07004202 DESCRIPTION
4203 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004204
Arun Menon906de572013-06-18 17:01:40 -07004205 PARAMETERS
4206 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004207
Arun Menon906de572013-06-18 17:01:40 -07004208 RETURN VALUE
4209 Error None if everything is successful.
4210 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004211OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004212 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004213{
Arun Menon906de572013-06-18 17:01:40 -07004214 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004215 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07004216 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004217}
4218
4219/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004220 FUNCTION
4221 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07004222
Arun Menon906de572013-06-18 17:01:40 -07004223 DESCRIPTION
4224 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004225
Arun Menon906de572013-06-18 17:01:40 -07004226 PARAMETERS
4227 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004228
Arun Menon906de572013-06-18 17:01:40 -07004229 RETURN VALUE
4230 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004231
Arun Menon906de572013-06-18 17:01:40 -07004232 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004233OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004234 OMX_IN OMX_U32 port,
4235 OMX_IN OMX_HANDLETYPE peerComponent,
4236 OMX_IN OMX_U32 peerPort,
4237 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004238{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004239 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07004240 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004241}
4242
4243/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004244 FUNCTION
4245 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004246
Arun Menon906de572013-06-18 17:01:40 -07004247 DESCRIPTION
4248 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004249
Arun Menon906de572013-06-18 17:01:40 -07004250 PARAMETERS
4251 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004252
Arun Menon906de572013-06-18 17:01:40 -07004253 RETURN VALUE
4254 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004255
Arun Menon906de572013-06-18 17:01:40 -07004256 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004257OMX_ERRORTYPE omx_vdec::allocate_extradata()
4258{
4259#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004260 if (drv_ctx.extradata_info.buffer_size) {
4261 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4262 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4263 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4264 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004265 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004266 }
4267 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4268 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4269 drv_ctx.extradata_info.size, 4096,
4270 &drv_ctx.extradata_info.ion.ion_alloc_data,
4271 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4272 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004273 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004274 return OMX_ErrorInsufficientResources;
4275 }
4276 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4277 drv_ctx.extradata_info.size,
4278 PROT_READ|PROT_WRITE, MAP_SHARED,
4279 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4280 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004281 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004282 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4283 free_ion_memory(&drv_ctx.extradata_info.ion);
4284 return OMX_ErrorInsufficientResources;
4285 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004286 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004287#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304288 if (!m_other_extradata) {
4289 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4290 if (!m_other_extradata) {
4291 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4292 return OMX_ErrorInsufficientResources;
4293 }
4294 }
Arun Menon906de572013-06-18 17:01:40 -07004295 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004296}
4297
Arun Menon906de572013-06-18 17:01:40 -07004298void omx_vdec::free_extradata()
4299{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004300#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004301 if (drv_ctx.extradata_info.uaddr) {
4302 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4303 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4304 free_ion_memory(&drv_ctx.extradata_info.ion);
4305 }
4306 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004307#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304308 if (m_other_extradata) {
4309 free(m_other_extradata);
4310 m_other_extradata = NULL;
4311 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004312}
4313
Shalaj Jain273b3e02012-06-22 19:08:03 -07004314OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004315 OMX_IN OMX_HANDLETYPE hComp,
4316 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4317 OMX_IN OMX_U32 port,
4318 OMX_IN OMX_PTR appData,
4319 OMX_IN OMX_U32 bytes,
4320 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004321{
Arun Menon906de572013-06-18 17:01:40 -07004322 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4323 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4324 unsigned i= 0; // Temporary counter
4325 struct vdec_setbuffer_cmd setbuffers;
4326 OMX_PTR privateAppData = NULL;
4327 private_handle_t *handle = NULL;
4328 OMX_U8 *buff = buffer;
4329 struct v4l2_buffer buf;
4330 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4331 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004332
Arun Menon906de572013-06-18 17:01:40 -07004333 if (!m_out_mem_ptr) {
4334 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4335 eRet = allocate_output_headers();
4336 if (eRet == OMX_ErrorNone)
4337 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004338 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004339
Arun Menon906de572013-06-18 17:01:40 -07004340 if (eRet == OMX_ErrorNone) {
4341 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4342 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4343 break;
4344 }
4345 }
4346 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004347
Arun Menon906de572013-06-18 17:01:40 -07004348 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004349 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004350 eRet = OMX_ErrorInsufficientResources;
4351 }
4352
Arun Menonbdb80b02013-08-12 17:45:54 -07004353 if (dynamic_buf_mode) {
4354 *bufferHdr = (m_out_mem_ptr + i );
4355 (*bufferHdr)->pBuffer = NULL;
4356 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4357 enum v4l2_buf_type buf_type;
4358 int rr = 0;
4359 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4360 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4361 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4362 return OMX_ErrorInsufficientResources;
4363 } else {
4364 streaming[CAPTURE_PORT] = true;
4365 DEBUG_PRINT_LOW("STREAMON Successful");
4366 }
4367 }
4368 BITMASK_SET(&m_out_bm_count,i);
4369 (*bufferHdr)->pAppPrivate = appData;
4370 (*bufferHdr)->pBuffer = buffer;
4371 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4372 return eRet;
4373 }
Arun Menon906de572013-06-18 17:01:40 -07004374 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004375#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004376 if (m_enable_android_native_buffers) {
4377 if (m_use_android_native_buffers) {
4378 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4379 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4380 handle = (private_handle_t *)nBuf->handle;
4381 privateAppData = params->pAppPrivate;
4382 } else {
4383 handle = (private_handle_t *)buff;
4384 privateAppData = appData;
4385 }
Arun Menon8544ead2014-05-08 17:42:29 -07004386 if (!handle) {
4387 DEBUG_PRINT_ERROR("handle is invalid");
4388 return OMX_ErrorBadParameter;
4389 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004390
Arun Menon906de572013-06-18 17:01:40 -07004391 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4392 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4393 " expected %u, got %lu",
4394 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4395 return OMX_ErrorBadParameter;
4396 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004397
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07004398 drv_ctx.op_buf.buffer_size = handle->size;
4399
Arun Menon906de572013-06-18 17:01:40 -07004400 if (!m_use_android_native_buffers) {
4401 if (!secure_mode) {
4402 buff = (OMX_U8*)mmap(0, handle->size,
4403 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4404 if (buff == MAP_FAILED) {
4405 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4406 return OMX_ErrorInsufficientResources;
4407 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004408 }
4409 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004410#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004411 native_buffer[i].nativehandle = handle;
4412 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004413#endif
Arun Menon906de572013-06-18 17:01:40 -07004414 if (!handle) {
4415 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4416 return OMX_ErrorBadParameter;
4417 }
4418 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4419 drv_ctx.ptr_outputbuffer[i].offset = 0;
4420 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4421 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4422 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4423 } else
4424#endif
4425
4426 if (!ouput_egl_buffers && !m_use_output_pmem) {
4427#ifdef USE_ION
4428 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4429 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4430 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4431 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4432 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004433 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 -07004434 return OMX_ErrorInsufficientResources;
4435 }
4436 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4437 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4438#else
4439 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4440 open (MEM_DEVICE,O_RDWR);
4441
4442 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004443 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004444 return OMX_ErrorInsufficientResources;
4445 }
4446
4447 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4448 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4449 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4450 open (MEM_DEVICE,O_RDWR);
4451 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004452 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004453 return OMX_ErrorInsufficientResources;
4454 }
4455 }
4456
4457 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4458 drv_ctx.op_buf.buffer_size,
4459 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004460 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004461 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4462 return OMX_ErrorInsufficientResources;
4463 }
4464#endif
4465 if (!secure_mode) {
4466 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4467 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4468 PROT_READ|PROT_WRITE, MAP_SHARED,
4469 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4470 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4471 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4472#ifdef USE_ION
4473 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4474#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004475 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004476 return OMX_ErrorInsufficientResources;
4477 }
4478 }
4479 drv_ctx.ptr_outputbuffer[i].offset = 0;
4480 privateAppData = appData;
4481 } else {
4482
4483 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4484 if (!appData || !bytes ) {
4485 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004486 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004487 return OMX_ErrorBadParameter;
4488 }
4489 }
4490
4491 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4492 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4493 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
Arun Menon8544ead2014-05-08 17:42:29 -07004494 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
Arun Menon906de572013-06-18 17:01:40 -07004495 !pmem_list->nEntries ||
4496 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004497 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004498 return OMX_ErrorBadParameter;
4499 }
4500 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4501 pmem_list->entryList->entry;
4502 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4503 pmem_info->pmem_fd);
4504 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4505 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4506 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4507 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4508 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4509 privateAppData = appData;
4510 }
4511 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4512 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304513 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4514 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4515 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004516
4517 *bufferHdr = (m_out_mem_ptr + i );
4518 if (secure_mode)
4519 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4520 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4521 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4522 sizeof (vdec_bufferpayload));
4523
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004524 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004525 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4526 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4527
4528 buf.index = i;
4529 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4530 buf.memory = V4L2_MEMORY_USERPTR;
4531 plane[0].length = drv_ctx.op_buf.buffer_size;
4532 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4533 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4534 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4535 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4536 plane[0].data_offset = 0;
4537 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4538 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4539 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4540 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4541#ifdef USE_ION
4542 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4543#endif
4544 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4545 plane[extra_idx].data_offset = 0;
4546 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004547 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004548 return OMX_ErrorBadParameter;
4549 }
Arun Menon906de572013-06-18 17:01:40 -07004550 buf.m.planes = plane;
4551 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004552
Arun Menon906de572013-06-18 17:01:40 -07004553 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004554 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004555 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004556 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004557 }
4558
Arun Menon906de572013-06-18 17:01:40 -07004559 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4560 enum v4l2_buf_type buf_type;
4561 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4562 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4563 return OMX_ErrorInsufficientResources;
4564 } else {
4565 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004566 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004567 }
4568 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004569
Arun Menon906de572013-06-18 17:01:40 -07004570 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4571 if (m_enable_android_native_buffers) {
4572 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4573 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4574 } else {
4575 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004576 }
Arun Menon906de572013-06-18 17:01:40 -07004577 (*bufferHdr)->pAppPrivate = privateAppData;
4578 BITMASK_SET(&m_out_bm_count,i);
4579 }
4580 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004581}
4582
4583/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004584 FUNCTION
4585 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004586
Arun Menon906de572013-06-18 17:01:40 -07004587 DESCRIPTION
4588 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004589
Arun Menon906de572013-06-18 17:01:40 -07004590 PARAMETERS
4591 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004592
Arun Menon906de572013-06-18 17:01:40 -07004593 RETURN VALUE
4594 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004595
Arun Menon906de572013-06-18 17:01:40 -07004596 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004597OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004598 OMX_IN OMX_HANDLETYPE hComp,
4599 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4600 OMX_IN OMX_U32 port,
4601 OMX_IN OMX_PTR appData,
4602 OMX_IN OMX_U32 bytes,
4603 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004604{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004605 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004606 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4607 if (!m_inp_heap_ptr)
4608 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4609 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4610 drv_ctx.ip_buf.actualcount);
4611 if (!m_phdr_pmem_ptr)
4612 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4613 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4614 drv_ctx.ip_buf.actualcount);
4615 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4616 DEBUG_PRINT_ERROR("Insufficent memory");
4617 eRet = OMX_ErrorInsufficientResources;
4618 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4619 input_use_buffer = true;
4620 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4621 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4622 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4623 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4624 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4625 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4626 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4627 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004628 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 -07004629 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4630 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004631 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004632 return OMX_ErrorInsufficientResources;
4633 }
4634 m_in_alloc_cnt++;
4635 } else {
4636 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4637 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004638 }
Arun Menon906de572013-06-18 17:01:40 -07004639 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004640}
4641
4642/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004643 FUNCTION
4644 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004645
Arun Menon906de572013-06-18 17:01:40 -07004646 DESCRIPTION
4647 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004648
Arun Menon906de572013-06-18 17:01:40 -07004649 PARAMETERS
4650 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004651
Arun Menon906de572013-06-18 17:01:40 -07004652 RETURN VALUE
4653 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004654
Arun Menon906de572013-06-18 17:01:40 -07004655 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004656OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004657 OMX_IN OMX_HANDLETYPE hComp,
4658 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4659 OMX_IN OMX_U32 port,
4660 OMX_IN OMX_PTR appData,
4661 OMX_IN OMX_U32 bytes,
4662 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004663{
Arun Menon906de572013-06-18 17:01:40 -07004664 OMX_ERRORTYPE error = OMX_ErrorNone;
4665 struct vdec_setbuffer_cmd setbuffers;
4666
Arun Menon8544ead2014-05-08 17:42:29 -07004667 if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
4668 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4669 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004670 }
Arun Menon906de572013-06-18 17:01:40 -07004671 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004672 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004673 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004674 }
Arun Menon906de572013-06-18 17:01:40 -07004675 if (port == OMX_CORE_INPUT_PORT_INDEX)
4676 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4677 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4678 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4679 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004680 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004681 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004682 }
Arun Menon906de572013-06-18 17:01:40 -07004683 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4684 if (error == OMX_ErrorNone) {
4685 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4686 // Send the callback now
4687 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4688 post_event(OMX_CommandStateSet,OMX_StateIdle,
4689 OMX_COMPONENT_GENERATE_EVENT);
4690 }
4691 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4692 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4693 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4694 post_event(OMX_CommandPortEnable,
4695 OMX_CORE_INPUT_PORT_INDEX,
4696 OMX_COMPONENT_GENERATE_EVENT);
4697 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4698 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4699 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4700 post_event(OMX_CommandPortEnable,
4701 OMX_CORE_OUTPUT_PORT_INDEX,
4702 OMX_COMPONENT_GENERATE_EVENT);
4703 }
4704 }
4705 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004706}
4707
4708OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004709 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004710{
Arun Menon906de572013-06-18 17:01:40 -07004711 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4712 if (m_inp_heap_ptr[bufferindex].pBuffer)
4713 free(m_inp_heap_ptr[bufferindex].pBuffer);
4714 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4715 }
4716 if (pmem_bufferHdr)
4717 free_input_buffer(pmem_bufferHdr);
4718 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004719}
4720
4721OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4722{
Arun Menon906de572013-06-18 17:01:40 -07004723 unsigned int index = 0;
4724 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4725 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004726 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004727
Arun Menon906de572013-06-18 17:01:40 -07004728 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004729 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004730
4731 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004732 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004733 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4734 struct vdec_setbuffer_cmd setbuffers;
4735 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4736 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4737 sizeof (vdec_bufferpayload));
4738 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004739 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004740 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004741 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004742 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4743 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4744 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4745 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4746 }
4747 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4748 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4749 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4750 free(m_desc_buffer_ptr[index].buf_addr);
4751 m_desc_buffer_ptr[index].buf_addr = NULL;
4752 m_desc_buffer_ptr[index].desc_data_size = 0;
4753 }
4754#ifdef USE_ION
4755 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4756#endif
4757 }
4758 }
4759
4760 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004761}
4762
4763OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4764{
Arun Menon906de572013-06-18 17:01:40 -07004765 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004766
Arun Menon906de572013-06-18 17:01:40 -07004767 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4768 return OMX_ErrorBadParameter;
4769 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004770
Arun Menon906de572013-06-18 17:01:40 -07004771 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004772 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004773
Arun Menon906de572013-06-18 17:01:40 -07004774 if (index < drv_ctx.op_buf.actualcount
4775 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004776 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004777 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004778
Arun Menon906de572013-06-18 17:01:40 -07004779 struct vdec_setbuffer_cmd setbuffers;
4780 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4781 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4782 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004783
4784 if (!dynamic_buf_mode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004785#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004786 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004787 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004788 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4789 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4790 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4791 }
Arun Menon906de572013-06-18 17:01:40 -07004792 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004793 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4794 } else {
4795#endif
4796 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4797 if (!secure_mode) {
4798 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4799 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4800 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4801 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4802 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4803 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4804 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4805 }
4806 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4807 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004808#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004809 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004810#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004811 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004812#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004813 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004814#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004815 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004816 if (release_output_done()) {
4817 free_extradata();
4818 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004819 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004820
Arun Menon906de572013-06-18 17:01:40 -07004821 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004822
4823}
4824
4825OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004826 OMX_BUFFERHEADERTYPE **bufferHdr,
4827 OMX_U32 port,
4828 OMX_PTR appData,
4829 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004830{
Arun Menon906de572013-06-18 17:01:40 -07004831 OMX_BUFFERHEADERTYPE *input = NULL;
4832 unsigned char *buf_addr = NULL;
4833 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4834 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004835
Arun Menon906de572013-06-18 17:01:40 -07004836 /* Sanity Check*/
4837 if (bufferHdr == NULL) {
4838 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004839 }
4840
Arun Menon906de572013-06-18 17:01:40 -07004841 if (m_inp_heap_ptr == NULL) {
4842 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4843 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4844 drv_ctx.ip_buf.actualcount);
4845 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4846 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4847 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004848
Arun Menon8544ead2014-05-08 17:42:29 -07004849 if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
4850 DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004851 return OMX_ErrorInsufficientResources;
4852 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004853 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004854
Arun Menon906de572013-06-18 17:01:40 -07004855 /*Find a Free index*/
4856 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4857 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004858 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004859 break;
4860 }
4861 }
4862
4863 if (i < drv_ctx.ip_buf.actualcount) {
4864 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4865
4866 if (buf_addr == NULL) {
4867 return OMX_ErrorInsufficientResources;
4868 }
4869
4870 *bufferHdr = (m_inp_heap_ptr + i);
4871 input = *bufferHdr;
4872 BITMASK_SET(&m_heap_inp_bm_count,i);
4873
4874 input->pBuffer = (OMX_U8 *)buf_addr;
4875 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4876 input->nVersion.nVersion = OMX_SPEC_VERSION;
4877 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4878 input->pAppPrivate = appData;
4879 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004880 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004881 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004882 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004883 /*Add the Buffers to freeq*/
4884 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4885 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004886 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004887 return OMX_ErrorInsufficientResources;
4888 }
4889 } else {
4890 return OMX_ErrorBadParameter;
4891 }
4892
4893 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004894
4895}
4896
4897
4898/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004899 FUNCTION
4900 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004901
Arun Menon906de572013-06-18 17:01:40 -07004902 DESCRIPTION
4903 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004904
Arun Menon906de572013-06-18 17:01:40 -07004905 PARAMETERS
4906 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004907
Arun Menon906de572013-06-18 17:01:40 -07004908 RETURN VALUE
4909 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004910
Arun Menon906de572013-06-18 17:01:40 -07004911 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004912OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004913 OMX_IN OMX_HANDLETYPE hComp,
4914 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4915 OMX_IN OMX_U32 port,
4916 OMX_IN OMX_PTR appData,
4917 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004918{
4919
Arun Menon906de572013-06-18 17:01:40 -07004920 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4921 struct vdec_setbuffer_cmd setbuffers;
4922 OMX_BUFFERHEADERTYPE *input = NULL;
4923 unsigned i = 0;
4924 unsigned char *buf_addr = NULL;
4925 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004926
Arun Menon906de572013-06-18 17:01:40 -07004927 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004928 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004929 bytes, drv_ctx.ip_buf.buffer_size);
4930 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004931 }
4932
Arun Menon906de572013-06-18 17:01:40 -07004933 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004934 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004935 drv_ctx.ip_buf.actualcount,
4936 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004937
Arun Menon906de572013-06-18 17:01:40 -07004938 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4939 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4940
4941 if (m_inp_mem_ptr == NULL) {
4942 return OMX_ErrorInsufficientResources;
4943 }
4944
4945 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4946 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4947
4948 if (drv_ctx.ptr_inputbuffer == NULL) {
4949 return OMX_ErrorInsufficientResources;
4950 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004951#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004952 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4953 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004954
Arun Menon906de572013-06-18 17:01:40 -07004955 if (drv_ctx.ip_buf_ion_info == NULL) {
4956 return OMX_ErrorInsufficientResources;
4957 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004958#endif
4959
Arun Menon906de572013-06-18 17:01:40 -07004960 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4961 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004962#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004963 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004964#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004965 }
4966 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004967
Arun Menon906de572013-06-18 17:01:40 -07004968 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4969 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004970 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004971 break;
4972 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004973 }
Arun Menon906de572013-06-18 17:01:40 -07004974
4975 if (i < drv_ctx.ip_buf.actualcount) {
4976 struct v4l2_buffer buf;
4977 struct v4l2_plane plane;
4978 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004979 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004980#ifdef USE_ION
4981 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4982 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4983 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4984 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4985 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4986 return OMX_ErrorInsufficientResources;
4987 }
4988 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4989#else
4990 pmem_fd = open (MEM_DEVICE,O_RDWR);
4991
4992 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004993 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004994 return OMX_ErrorInsufficientResources;
4995 }
4996
4997 if (pmem_fd == 0) {
4998 pmem_fd = open (MEM_DEVICE,O_RDWR);
4999
5000 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005001 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005002 return OMX_ErrorInsufficientResources;
5003 }
5004 }
5005
5006 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
5007 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005008 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005009 close(pmem_fd);
5010 return OMX_ErrorInsufficientResources;
5011 }
5012#endif
5013 if (!secure_mode) {
5014 buf_addr = (unsigned char *)mmap(NULL,
5015 drv_ctx.ip_buf.buffer_size,
5016 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
5017
5018 if (buf_addr == MAP_FAILED) {
5019 close(pmem_fd);
5020#ifdef USE_ION
5021 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
5022#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005023 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005024 return OMX_ErrorInsufficientResources;
5025 }
5026 }
5027 *bufferHdr = (m_inp_mem_ptr + i);
5028 if (secure_mode)
5029 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
5030 else
5031 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
5032 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
5033 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
5034 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
5035 drv_ctx.ptr_inputbuffer [i].offset = 0;
5036
5037
5038 buf.index = i;
5039 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5040 buf.memory = V4L2_MEMORY_USERPTR;
5041 plane.bytesused = 0;
5042 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
5043 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
5044 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
5045 plane.reserved[1] = 0;
5046 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
5047 buf.m.planes = &plane;
5048 buf.length = 1;
5049
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005050 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07005051 drv_ctx.ptr_inputbuffer[i].bufferaddr);
5052
5053 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5054
5055 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005056 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07005057 /*TODO: How to handle this case */
5058 return OMX_ErrorInsufficientResources;
5059 }
5060
5061 input = *bufferHdr;
5062 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005063 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07005064 if (secure_mode)
5065 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
5066 else
5067 input->pBuffer = (OMX_U8 *)buf_addr;
5068 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5069 input->nVersion.nVersion = OMX_SPEC_VERSION;
5070 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
5071 input->pAppPrivate = appData;
5072 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
5073 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
5074
5075 if (drv_ctx.disable_dmx) {
5076 eRet = allocate_desc_buffer(i);
5077 }
5078 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005079 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07005080 eRet = OMX_ErrorInsufficientResources;
5081 }
5082 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005083}
5084
5085
5086/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005087 FUNCTION
5088 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005089
Arun Menon906de572013-06-18 17:01:40 -07005090 DESCRIPTION
5091 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07005092
Arun Menon906de572013-06-18 17:01:40 -07005093 PARAMETERS
5094 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005095
Arun Menon906de572013-06-18 17:01:40 -07005096 RETURN VALUE
5097 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005098
Arun Menon906de572013-06-18 17:01:40 -07005099 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005100OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07005101 OMX_IN OMX_HANDLETYPE hComp,
5102 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5103 OMX_IN OMX_U32 port,
5104 OMX_IN OMX_PTR appData,
5105 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005106{
Arun Menon906de572013-06-18 17:01:40 -07005107 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5108 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
5109 unsigned i= 0; // Temporary counter
5110 struct vdec_setbuffer_cmd setbuffers;
5111 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005112#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005113 int ion_device_fd =-1;
5114 struct ion_allocation_data ion_alloc_data;
5115 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005116#endif
Arun Menon906de572013-06-18 17:01:40 -07005117 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005118 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07005119 drv_ctx.op_buf.actualcount,
5120 drv_ctx.op_buf.buffer_size);
5121 int nBufHdrSize = 0;
5122 int nPlatformEntrySize = 0;
5123 int nPlatformListSize = 0;
5124 int nPMEMInfoSize = 0;
5125 int pmem_fd = -1;
5126 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005127
Arun Menon906de572013-06-18 17:01:40 -07005128 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
5129 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
5130 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005131
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005132 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07005133 drv_ctx.op_buf.actualcount);
5134 nBufHdrSize = drv_ctx.op_buf.actualcount *
5135 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005136
Arun Menon906de572013-06-18 17:01:40 -07005137 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
5138 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
5139 nPlatformListSize = drv_ctx.op_buf.actualcount *
5140 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
5141 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
5142 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005143
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005144 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07005145 sizeof(OMX_BUFFERHEADERTYPE),
5146 nPMEMInfoSize,
5147 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005148 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07005149 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005150#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005151 ion_device_fd = alloc_map_ion_memory(
5152 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
5153 drv_ctx.op_buf.alignment,
5154 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
5155 if (ion_device_fd < 0) {
5156 return OMX_ErrorInsufficientResources;
5157 }
5158 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005159#else
Arun Menon906de572013-06-18 17:01:40 -07005160 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005161
Arun Menon906de572013-06-18 17:01:40 -07005162 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005163 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005164 drv_ctx.op_buf.buffer_size);
5165 return OMX_ErrorInsufficientResources;
5166 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005167
Arun Menon906de572013-06-18 17:01:40 -07005168 if (pmem_fd == 0) {
5169 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005170
Arun Menon906de572013-06-18 17:01:40 -07005171 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005172 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005173 drv_ctx.op_buf.buffer_size);
5174 return OMX_ErrorInsufficientResources;
5175 }
5176 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005177
Arun Menon906de572013-06-18 17:01:40 -07005178 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5179 drv_ctx.op_buf.actualcount,
5180 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005181 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005182 close(pmem_fd);
5183 return OMX_ErrorInsufficientResources;
5184 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005185#endif
Arun Menon906de572013-06-18 17:01:40 -07005186 if (!secure_mode) {
5187 pmem_baseaddress = (unsigned char *)mmap(NULL,
5188 (drv_ctx.op_buf.buffer_size *
5189 drv_ctx.op_buf.actualcount),
5190 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5191 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005192 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07005193 drv_ctx.op_buf.buffer_size);
5194 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005195#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005196 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005197#endif
Arun Menon906de572013-06-18 17:01:40 -07005198 return OMX_ErrorInsufficientResources;
5199 }
5200 }
5201 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5202 // Alloc mem for platform specific info
5203 char *pPtr=NULL;
5204 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5205 nPMEMInfoSize,1);
5206 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5207 calloc (sizeof(struct vdec_bufferpayload),
5208 drv_ctx.op_buf.actualcount);
5209 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5210 calloc (sizeof (struct vdec_output_frameinfo),
5211 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005212 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
5213 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
5214 return OMX_ErrorInsufficientResources;
5215 }
5216
Arun Menon906de572013-06-18 17:01:40 -07005217#ifdef USE_ION
5218 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5219 calloc (sizeof(struct vdec_ion),
5220 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005221 if (!drv_ctx.op_buf_ion_info) {
5222 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
5223 return OMX_ErrorInsufficientResources;
5224 }
Arun Menon906de572013-06-18 17:01:40 -07005225#endif
5226
5227 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5228 && drv_ctx.ptr_respbuffer) {
5229 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5230 (drv_ctx.op_buf.buffer_size *
5231 drv_ctx.op_buf.actualcount);
5232 bufHdr = m_out_mem_ptr;
5233 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5234 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5235 (((char *) m_platform_list) + nPlatformListSize);
5236 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5237 (((char *) m_platform_entry) + nPlatformEntrySize);
5238 pPlatformList = m_platform_list;
5239 pPlatformEntry = m_platform_entry;
5240 pPMEMInfo = m_pmem_info;
5241
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005242 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07005243
5244 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005245 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
5246 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07005247 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
5248 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5249 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5250 // Set the values when we determine the right HxW param
5251 bufHdr->nAllocLen = bytes;
5252 bufHdr->nFilledLen = 0;
5253 bufHdr->pAppPrivate = appData;
5254 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5255 // Platform specific PMEM Information
5256 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005257 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005258 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5259 pPlatformEntry->entry = pPMEMInfo;
5260 // Initialize the Platform List
5261 pPlatformList->nEntries = 1;
5262 pPlatformList->entryList = pPlatformEntry;
5263 // Keep pBuffer NULL till vdec is opened
5264 bufHdr->pBuffer = NULL;
5265 bufHdr->nOffset = 0;
5266
5267 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5268 pPMEMInfo->pmem_fd = 0;
5269 bufHdr->pPlatformPrivate = pPlatformList;
5270
5271 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5272 m_pmem_info[i].pmem_fd = pmem_fd;
5273#ifdef USE_ION
5274 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5275 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5276 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5277#endif
5278
5279 /*Create a mapping between buffers*/
5280 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5281 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5282 &drv_ctx.ptr_outputbuffer[i];
5283 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5284 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5285 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305286 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5287 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5288 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005289
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005290 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005291 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5292 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5293 // Move the buffer and buffer header pointers
5294 bufHdr++;
5295 pPMEMInfo++;
5296 pPlatformEntry++;
5297 pPlatformList++;
5298 }
5299 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005300 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005301 m_out_mem_ptr, pPtr);
5302 if (m_out_mem_ptr) {
5303 free(m_out_mem_ptr);
5304 m_out_mem_ptr = NULL;
5305 }
5306 if (pPtr) {
5307 free(pPtr);
5308 pPtr = NULL;
5309 }
5310 if (drv_ctx.ptr_outputbuffer) {
5311 free(drv_ctx.ptr_outputbuffer);
5312 drv_ctx.ptr_outputbuffer = NULL;
5313 }
5314 if (drv_ctx.ptr_respbuffer) {
5315 free(drv_ctx.ptr_respbuffer);
5316 drv_ctx.ptr_respbuffer = NULL;
5317 }
5318#ifdef USE_ION
5319 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005320 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005321 free(drv_ctx.op_buf_ion_info);
5322 drv_ctx.op_buf_ion_info = NULL;
5323 }
5324#endif
5325 eRet = OMX_ErrorInsufficientResources;
5326 }
5327 if (eRet == OMX_ErrorNone)
5328 eRet = allocate_extradata();
5329 }
5330
5331 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5332 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005333 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005334 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005335 }
5336 }
Arun Menon906de572013-06-18 17:01:40 -07005337
5338 if (eRet == OMX_ErrorNone) {
5339 if (i < drv_ctx.op_buf.actualcount) {
5340 struct v4l2_buffer buf;
5341 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5342 int rc;
5343 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5344
5345 drv_ctx.ptr_outputbuffer[i].buffer_len =
5346 drv_ctx.op_buf.buffer_size;
5347
5348 *bufferHdr = (m_out_mem_ptr + i );
5349 if (secure_mode) {
5350 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5351 }
5352 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5353
5354 buf.index = i;
5355 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5356 buf.memory = V4L2_MEMORY_USERPTR;
5357 plane[0].length = drv_ctx.op_buf.buffer_size;
5358 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5359 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005360#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005361 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005362#endif
Arun Menon906de572013-06-18 17:01:40 -07005363 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5364 plane[0].data_offset = 0;
5365 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5366 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5367 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5368 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 -07005369#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005370 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005371#endif
Arun Menon906de572013-06-18 17:01:40 -07005372 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5373 plane[extra_idx].data_offset = 0;
5374 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005375 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005376 return OMX_ErrorBadParameter;
5377 }
5378 buf.m.planes = plane;
5379 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005380 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 -07005381 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5382 if (rc) {
5383 /*TODO: How to handle this case */
5384 return OMX_ErrorInsufficientResources;
5385 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005386
Arun Menon906de572013-06-18 17:01:40 -07005387 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5388 enum v4l2_buf_type buf_type;
5389 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5390 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5391 if (rc) {
5392 return OMX_ErrorInsufficientResources;
5393 } else {
5394 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005395 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005396 }
5397 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005398
Arun Menon906de572013-06-18 17:01:40 -07005399 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5400 (*bufferHdr)->pAppPrivate = appData;
5401 BITMASK_SET(&m_out_bm_count,i);
5402 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005403 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005404 eRet = OMX_ErrorInsufficientResources;
5405 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005406 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005407
Arun Menon906de572013-06-18 17:01:40 -07005408 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005409}
5410
5411
5412// AllocateBuffer -- API Call
5413/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005414 FUNCTION
5415 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005416
Arun Menon906de572013-06-18 17:01:40 -07005417 DESCRIPTION
5418 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005419
Arun Menon906de572013-06-18 17:01:40 -07005420 PARAMETERS
5421 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005422
Arun Menon906de572013-06-18 17:01:40 -07005423 RETURN VALUE
5424 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005425
Arun Menon906de572013-06-18 17:01:40 -07005426 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005427OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005428 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5429 OMX_IN OMX_U32 port,
5430 OMX_IN OMX_PTR appData,
5431 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005432{
5433 unsigned i = 0;
5434 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5435
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005436 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005437 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005438 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005439 return OMX_ErrorInvalidState;
5440 }
5441
Arun Menon906de572013-06-18 17:01:40 -07005442 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5443 if (arbitrary_bytes) {
5444 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5445 } else {
5446 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5447 }
5448 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005449 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5450 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005451 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005452 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005453 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005454 }
5455 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005456 if (eRet == OMX_ErrorNone) {
5457 if (allocate_done()) {
5458 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005459 // Send the callback now
5460 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5461 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005462 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005463 }
5464 }
Arun Menon906de572013-06-18 17:01:40 -07005465 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5466 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5467 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5468 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005469 OMX_CORE_INPUT_PORT_INDEX,
5470 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005471 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005472 }
Arun Menon906de572013-06-18 17:01:40 -07005473 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5474 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5475 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005476 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005477 OMX_CORE_OUTPUT_PORT_INDEX,
5478 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005479 }
5480 }
5481 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005482 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005483 return eRet;
5484}
5485
5486// Free Buffer - API call
5487/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005488 FUNCTION
5489 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005490
Arun Menon906de572013-06-18 17:01:40 -07005491 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005492
Arun Menon906de572013-06-18 17:01:40 -07005493 PARAMETERS
5494 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005495
Arun Menon906de572013-06-18 17:01:40 -07005496 RETURN VALUE
5497 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005498
Arun Menon906de572013-06-18 17:01:40 -07005499 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005500OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005501 OMX_IN OMX_U32 port,
5502 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005503{
5504 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5505 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005506 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005507
Arun Menon906de572013-06-18 17:01:40 -07005508 if (m_state == OMX_StateIdle &&
5509 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005510 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005511 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5512 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005513 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005514 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5515 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5516 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5517 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005518 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005519 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005520 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005521 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005522 OMX_ErrorPortUnpopulated,
5523 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005524
5525 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005526 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005527 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005528 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005529 OMX_ErrorPortUnpopulated,
5530 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005531 }
5532
Arun Menon906de572013-06-18 17:01:40 -07005533 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5534 /*Check if arbitrary bytes*/
5535 if (!arbitrary_bytes && !input_use_buffer)
5536 nPortIndex = buffer - m_inp_mem_ptr;
5537 else
5538 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005539
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005540 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005541 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5542 // Clear the bit associated with it.
5543 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5544 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5545 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005546
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005547 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005548 if (m_phdr_pmem_ptr)
5549 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5550 } else {
5551 if (arbitrary_bytes) {
5552 if (m_phdr_pmem_ptr)
5553 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5554 else
5555 free_input_buffer(nPortIndex,NULL);
5556 } else
5557 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005558 }
Arun Menon906de572013-06-18 17:01:40 -07005559 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305560 if(release_input_done())
5561 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005562 /*Free the Buffer Header*/
5563 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005564 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005565 free_input_buffer_header();
5566 }
5567 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005568 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005569 eRet = OMX_ErrorBadPortIndex;
5570 }
5571
Arun Menon906de572013-06-18 17:01:40 -07005572 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5573 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005574 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005575 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5576 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005577 OMX_CORE_INPUT_PORT_INDEX,
5578 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005579 }
Arun Menon906de572013-06-18 17:01:40 -07005580 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005581 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005582 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005583 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005584 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005585 // Clear the bit associated with it.
5586 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5587 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005588 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005589
Surajit Podder12aefac2013-08-06 18:43:32 +05305590 if(release_output_done()) {
5591 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5592 }
Arun Menon906de572013-06-18 17:01:40 -07005593 if (release_output_done()) {
5594 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005595 }
Arun Menon906de572013-06-18 17:01:40 -07005596 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005597 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005598 eRet = OMX_ErrorBadPortIndex;
5599 }
Arun Menon906de572013-06-18 17:01:40 -07005600 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5601 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005602 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005603
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005604 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005605 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005606#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005607 if (m_enable_android_native_buffers) {
5608 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5609 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5610 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005611#endif
5612
Arun Menon906de572013-06-18 17:01:40 -07005613 post_event(OMX_CommandPortDisable,
5614 OMX_CORE_OUTPUT_PORT_INDEX,
5615 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005616 }
Arun Menon906de572013-06-18 17:01:40 -07005617 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005618 eRet = OMX_ErrorBadPortIndex;
5619 }
Arun Menon906de572013-06-18 17:01:40 -07005620 if ((eRet == OMX_ErrorNone) &&
5621 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5622 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005623 // Send the callback now
5624 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5625 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005626 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005627 }
5628 }
5629 return eRet;
5630}
5631
5632
5633/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005634 FUNCTION
5635 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005636
Arun Menon906de572013-06-18 17:01:40 -07005637 DESCRIPTION
5638 This routine is used to push the encoded video frames to
5639 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005640
Arun Menon906de572013-06-18 17:01:40 -07005641 PARAMETERS
5642 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005643
Arun Menon906de572013-06-18 17:01:40 -07005644 RETURN VALUE
5645 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005646
Arun Menon906de572013-06-18 17:01:40 -07005647 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005648OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005649 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005650{
Arun Menon906de572013-06-18 17:01:40 -07005651 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5652 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005653
Arun Menon906de572013-06-18 17:01:40 -07005654 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005655 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005656 return OMX_ErrorInvalidState;
5657 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005658
Arun Menon906de572013-06-18 17:01:40 -07005659 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005660 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005661 return OMX_ErrorBadParameter;
5662 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005663
Arun Menon906de572013-06-18 17:01:40 -07005664 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005665 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005666 return OMX_ErrorIncorrectStateOperation;
5667 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005668
Arun Menon906de572013-06-18 17:01:40 -07005669 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005670 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005671 return OMX_ErrorBadPortIndex;
5672 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005673
5674#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005675 if (iDivXDrmDecrypt) {
5676 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5677 if (drmErr != OMX_ErrorNone) {
5678 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005679 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005680 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005681 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005682#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005683 if (perf_flag) {
5684 if (!latency) {
5685 dec_time.stop();
5686 latency = dec_time.processing_time_us();
5687 dec_time.start();
5688 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005689 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005690
Arun Menon906de572013-06-18 17:01:40 -07005691 if (arbitrary_bytes) {
5692 nBufferIndex = buffer - m_inp_heap_ptr;
5693 } else {
5694 if (input_use_buffer == true) {
5695 nBufferIndex = buffer - m_inp_heap_ptr;
5696 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5697 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5698 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5699 buffer = &m_inp_mem_ptr[nBufferIndex];
5700 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5701 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5702 } else {
5703 nBufferIndex = buffer - m_inp_mem_ptr;
5704 }
5705 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005706
Arun Menon906de572013-06-18 17:01:40 -07005707 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005708 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005709 return OMX_ErrorBadParameter;
5710 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005711
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005712 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5713 codec_config_flag = true;
5714 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5715 }
5716
Arun Menon906de572013-06-18 17:01:40 -07005717 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5718 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5719 if (arbitrary_bytes) {
5720 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005721 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005722 } else {
Arun Menon906de572013-06-18 17:01:40 -07005723 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5724 }
5725 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005726}
5727
5728/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005729 FUNCTION
5730 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005731
Arun Menon906de572013-06-18 17:01:40 -07005732 DESCRIPTION
5733 This routine is used to push the encoded video frames to
5734 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005735
Arun Menon906de572013-06-18 17:01:40 -07005736 PARAMETERS
5737 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005738
Arun Menon906de572013-06-18 17:01:40 -07005739 RETURN VALUE
5740 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005741
Arun Menon906de572013-06-18 17:01:40 -07005742 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005743OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005744 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005745{
Arun Menon906de572013-06-18 17:01:40 -07005746 int push_cnt = 0,i=0;
5747 unsigned nPortIndex = 0;
5748 OMX_ERRORTYPE ret = OMX_ErrorNone;
5749 struct vdec_input_frameinfo frameinfo;
5750 struct vdec_bufferpayload *temp_buffer;
5751 struct vdec_seqheader seq_header;
5752 bool port_setting_changed = true;
5753 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005754
Arun Menon906de572013-06-18 17:01:40 -07005755 /*Should we generate a Aync error event*/
5756 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005757 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005758 return OMX_ErrorBadParameter;
5759 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005760
Arun Menon906de572013-06-18 17:01:40 -07005761 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005762
Arun Menon906de572013-06-18 17:01:40 -07005763 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005764 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005765 nPortIndex);
5766 return OMX_ErrorBadParameter;
5767 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005768
Arun Menon906de572013-06-18 17:01:40 -07005769 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005770
Arun Menon906de572013-06-18 17:01:40 -07005771 /* return zero length and not an EOS buffer */
5772 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5773 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005774 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005775 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5776 OMX_COMPONENT_GENERATE_EBD);
5777 return OMX_ErrorNone;
5778 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005779
5780
Deva Ramasubramanian286a3582014-08-25 18:09:38 -07005781 if (ignore_not_coded_vops &&
5782 (codec_type_parse == CODEC_TYPE_MPEG4 ||
5783 codec_type_parse == CODEC_TYPE_DIVX)) {
Arun Menon906de572013-06-18 17:01:40 -07005784 mp4StreamType psBits;
5785 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5786 psBits.numBytes = buffer->nFilledLen;
5787 mp4_headerparser.parseHeader(&psBits);
5788 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5789 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5790 if (not_coded_vop) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005791 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u",
Arun Menon906de572013-06-18 17:01:40 -07005792 buffer->nFilledLen,frame_count);
5793 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005794 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
Arun Menon906de572013-06-18 17:01:40 -07005795 not_coded_vop = false;
5796 buffer->nFilledLen = 0;
5797 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005798 }
5799 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005800
Arun Menon906de572013-06-18 17:01:40 -07005801 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005802
Arun Menon906de572013-06-18 17:01:40 -07005803 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005804
Arun Menon906de572013-06-18 17:01:40 -07005805 ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005806 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005807 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5808 OMX_COMPONENT_GENERATE_EBD);
5809 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005810 }
5811
Arun Menon906de572013-06-18 17:01:40 -07005812 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005813
Surajit Podderd2644d52013-08-28 17:59:06 +05305814 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005815 return OMX_ErrorBadParameter;
5816 }
5817 /* If its first frame, H264 codec and reject is true, then parse the nal
5818 and get the profile. Based on this, reject the clip playback */
5819 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5820 m_reject_avc_1080p_mp) {
5821 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005822 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005823 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5824 NALU_TYPE_SPS);
5825 m_profile = h264_parser->get_profile();
5826 ret = is_video_session_supported();
5827 if (ret) {
5828 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5829 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5830 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5831 m_state = OMX_StateInvalid;
5832 return OMX_ErrorNone;
5833 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005834 }
5835
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005836 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005837 /*for use buffer we need to memcpy the data*/
5838 temp_buffer->buffer_len = buffer->nFilledLen;
5839
5840 if (input_use_buffer) {
5841 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5842 if (arbitrary_bytes) {
5843 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5844 } else {
5845 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5846 buffer->nFilledLen);
5847 }
5848 } else {
5849 return OMX_ErrorBadParameter;
5850 }
5851
5852 }
5853
5854 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5855 frameinfo.client_data = (void *) buffer;
5856 frameinfo.datalen = temp_buffer->buffer_len;
5857 frameinfo.flags = 0;
5858 frameinfo.offset = buffer->nOffset;
5859 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5860 frameinfo.pmem_offset = temp_buffer->offset;
5861 frameinfo.timestamp = buffer->nTimeStamp;
5862 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5863 DEBUG_PRINT_LOW("ETB: dmx enabled");
5864 if (m_demux_entries == 0) {
5865 extract_demux_addr_offsets(buffer);
5866 }
5867
5868 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5869 handle_demux_data(buffer);
5870 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5871 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5872 } else {
5873 frameinfo.desc_addr = NULL;
5874 frameinfo.desc_size = 0;
5875 }
5876 if (!arbitrary_bytes) {
5877 frameinfo.flags |= buffer->nFlags;
5878 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005879
5880#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005881 if (m_debug_timestamp) {
5882 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005883 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005884 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5885 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005886 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005887 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5888 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005889 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005890#endif
5891
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005892log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005893
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005894if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005895 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5896 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5897 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005898
Arun Menon906de572013-06-18 17:01:40 -07005899 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005900 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005901 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5902 h264_scratch.nFilledLen = 0;
5903 nal_count = 0;
5904 look_ahead_nal = false;
5905 frame_count = 0;
5906 if (m_frame_parser.mutils)
5907 m_frame_parser.mutils->initialize_frame_checking_environment();
5908 m_frame_parser.flush();
5909 h264_last_au_ts = LLONG_MAX;
5910 h264_last_au_flags = 0;
5911 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5912 m_demux_entries = 0;
5913 }
5914 struct v4l2_buffer buf;
5915 struct v4l2_plane plane;
5916 memset( (void *)&buf, 0, sizeof(buf));
5917 memset( (void *)&plane, 0, sizeof(plane));
5918 int rc;
5919 unsigned long print_count;
5920 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005921 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005922 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005923 }
5924 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5925 buf.index = nPortIndex;
5926 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5927 buf.memory = V4L2_MEMORY_USERPTR;
5928 plane.bytesused = temp_buffer->buffer_len;
5929 plane.length = drv_ctx.ip_buf.buffer_size;
5930 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5931 (unsigned long)temp_buffer->offset;
5932 plane.reserved[0] = temp_buffer->pmem_fd;
5933 plane.reserved[1] = temp_buffer->offset;
5934 plane.data_offset = 0;
5935 buf.m.planes = &plane;
5936 buf.length = 1;
5937 if (frameinfo.timestamp >= LLONG_MAX) {
5938 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5939 }
5940 //assumption is that timestamp is in milliseconds
5941 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5942 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5943 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5944 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005945
Pushkaraj Patil20bd6bf2014-12-22 19:33:08 +05305946 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5947 DEBUG_PRINT_LOW("Increment codec_config buffer counter");
5948 android_atomic_inc(&m_queued_codec_config_count);
5949 }
5950
Arun Menon906de572013-06-18 17:01:40 -07005951 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5952 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005953 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005954 return OMX_ErrorHardware;
5955 }
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -07005956
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005957 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5958 codec_config_flag = false;
5959 }
Arun Menon906de572013-06-18 17:01:40 -07005960 if (!streaming[OUTPUT_PORT]) {
5961 enum v4l2_buf_type buf_type;
5962 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005963
Arun Menon906de572013-06-18 17:01:40 -07005964 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005965 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005966 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5967 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005968 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005969 streaming[OUTPUT_PORT] = true;
Jia Meng1e236c82014-04-03 10:54:39 +08005970 } else if (errno == EBUSY) {
5971 DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
5972 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
5973 OMX_COMPONENT_GENERATE_EBD);
5974 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005975 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005976 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005977 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
Jia Meng1e236c82014-04-03 10:54:39 +08005978 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
Arun Menon906de572013-06-18 17:01:40 -07005979 OMX_COMPONENT_GENERATE_EBD);
5980 return OMX_ErrorBadParameter;
5981 }
5982 }
5983 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5984 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5985 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005986
Arun Menon906de572013-06-18 17:01:40 -07005987 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005988}
5989
5990/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005991 FUNCTION
5992 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005993
Arun Menon906de572013-06-18 17:01:40 -07005994 DESCRIPTION
5995 IL client uses this method to release the frame buffer
5996 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005997
Arun Menon906de572013-06-18 17:01:40 -07005998 PARAMETERS
5999 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006000
Arun Menon906de572013-06-18 17:01:40 -07006001 RETURN VALUE
6002 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006003
Arun Menon906de572013-06-18 17:01:40 -07006004 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006005OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006006 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006007{
Jia Meng2d51b932014-07-10 14:02:54 +08006008 unsigned nPortIndex = 0;
Arun Menonbdb80b02013-08-12 17:45:54 -07006009 if (dynamic_buf_mode) {
6010 private_handle_t *handle = NULL;
6011 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07006012 unsigned int nPortIndex = 0;
6013
6014 if (!buffer || !buffer->pBuffer) {
Arun Menon8544ead2014-05-08 17:42:29 -07006015 DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
Arun Menonbdb80b02013-08-12 17:45:54 -07006016 return OMX_ErrorBadParameter;
6017 }
6018
6019 //get the buffer type and fd info
6020 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
6021 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08006022 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
6023
6024 if (!handle) {
6025 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
6026 return OMX_ErrorBadParameter;
6027 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006028 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
6029 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6030 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08006031 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006032
6033 //Store private handle from GraphicBuffer
6034 native_buffer[nPortIndex].privatehandle = handle;
6035 native_buffer[nPortIndex].nativehandle = handle;
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006036
6037 //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
6038 //this with a more sane size so that we don't compensate in rest of code
6039 //We'll restore this size later on, so that it's transparent to client
6040 buffer->nFilledLen = 0;
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07006041 buffer->nAllocLen = handle->size;
Arun Menonbdb80b02013-08-12 17:45:54 -07006042 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006043
Arun Menon906de572013-06-18 17:01:40 -07006044 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006045 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07006046 return OMX_ErrorInvalidState;
6047 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006048
Arun Menon906de572013-06-18 17:01:40 -07006049 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006050 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07006051 return OMX_ErrorIncorrectStateOperation;
6052 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006053
Jia Meng2d51b932014-07-10 14:02:54 +08006054 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07006055 if (buffer == NULL ||
Jia Meng2d51b932014-07-10 14:02:54 +08006056 (nPortIndex >= drv_ctx.op_buf.actualcount)) {
6057 DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
6058 nPortIndex, drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07006059 return OMX_ErrorBadParameter;
6060 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006061
Arun Menon906de572013-06-18 17:01:40 -07006062 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006063 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07006064 return OMX_ErrorBadPortIndex;
6065 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006066
Arun Menon906de572013-06-18 17:01:40 -07006067 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6068 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
6069 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006070}
6071/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006072 FUNCTION
6073 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07006074
Arun Menon906de572013-06-18 17:01:40 -07006075 DESCRIPTION
6076 IL client uses this method to release the frame buffer
6077 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006078
Arun Menon906de572013-06-18 17:01:40 -07006079 PARAMETERS
6080 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006081
Arun Menon906de572013-06-18 17:01:40 -07006082 RETURN VALUE
6083 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006084
Arun Menon906de572013-06-18 17:01:40 -07006085 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006086OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07006087 OMX_IN OMX_HANDLETYPE hComp,
6088 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006089{
Arun Menon906de572013-06-18 17:01:40 -07006090 OMX_ERRORTYPE nRet = OMX_ErrorNone;
6091 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
6092 unsigned nPortIndex = 0;
6093 struct vdec_fillbuffer_cmd fillbuffer;
6094 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
6095 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006096
Arun Menon906de572013-06-18 17:01:40 -07006097 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07006098
Jia Meng2d51b932014-07-10 14:02:54 +08006099 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) {
6100 DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
6101 nPortIndex, drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07006102 return OMX_ErrorBadParameter;
Jia Meng2d51b932014-07-10 14:02:54 +08006103 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006104
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006105 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006106 bufferAdd, bufferAdd->pBuffer);
6107 /*Return back the output buffer to client*/
6108 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006109 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07006110 buffer->nFilledLen = 0;
6111 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6112 return OMX_ErrorNone;
6113 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08006114
6115 if (dynamic_buf_mode) {
6116 //map the buffer handle based on the size set on output port definition.
6117 if (!secure_mode) {
6118 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
6119 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
6120 PROT_READ|PROT_WRITE, MAP_SHARED,
6121 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
6122 }
6123 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
6124 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
6125 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
6126 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
6127 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
6128 }
6129
Arun Menon906de572013-06-18 17:01:40 -07006130 pending_output_buffers++;
6131 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
6132 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
6133 if (ptr_respbuffer) {
6134 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
6135 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006136
Arun Menon906de572013-06-18 17:01:40 -07006137 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
6138 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
6139 buffer->nFilledLen = 0;
6140 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6141 pending_output_buffers--;
6142 return OMX_ErrorBadParameter;
6143 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006144
Arun Menon906de572013-06-18 17:01:40 -07006145 int rc = 0;
6146 struct v4l2_buffer buf;
6147 struct v4l2_plane plane[VIDEO_MAX_PLANES];
6148 memset( (void *)&buf, 0, sizeof(buf));
6149 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Arun Menon8544ead2014-05-08 17:42:29 -07006150 unsigned int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006151
Arun Menon906de572013-06-18 17:01:40 -07006152 buf.index = nPortIndex;
6153 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6154 buf.memory = V4L2_MEMORY_USERPTR;
6155 plane[0].bytesused = buffer->nFilledLen;
6156 plane[0].length = drv_ctx.op_buf.buffer_size;
6157 plane[0].m.userptr =
6158 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
6159 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6160 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
6161 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6162 plane[0].data_offset = 0;
6163 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
6164 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
6165 plane[extra_idx].bytesused = 0;
6166 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
6167 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 -07006168#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07006169 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006170#endif
Arun Menon906de572013-06-18 17:01:40 -07006171 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
6172 plane[extra_idx].data_offset = 0;
6173 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Arun Menon8544ead2014-05-08 17:42:29 -07006174 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07006175 return OMX_ErrorBadParameter;
6176 }
6177 buf.m.planes = plane;
6178 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006179 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07006180 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
6181
Arun Menon906de572013-06-18 17:01:40 -07006182 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6183 if (rc) {
6184 /*TODO: How to handle this case */
6185 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6186 }
Arun Menon906de572013-06-18 17:01:40 -07006187return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006188}
6189
6190/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006191 FUNCTION
6192 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07006193
Arun Menon906de572013-06-18 17:01:40 -07006194 DESCRIPTION
6195 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006196
Arun Menon906de572013-06-18 17:01:40 -07006197 PARAMETERS
6198 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006199
Arun Menon906de572013-06-18 17:01:40 -07006200 RETURN VALUE
6201 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006202
Arun Menon906de572013-06-18 17:01:40 -07006203 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006204OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006205 OMX_IN OMX_CALLBACKTYPE* callbacks,
6206 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006207{
6208
Arun Menon906de572013-06-18 17:01:40 -07006209 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006210 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07006211 m_cb.EventHandler,m_cb.FillBufferDone);
6212 m_app_data = appData;
6213 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006214}
6215
6216/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006217 FUNCTION
6218 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07006219
Arun Menon906de572013-06-18 17:01:40 -07006220 DESCRIPTION
6221 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006222
Arun Menon906de572013-06-18 17:01:40 -07006223 PARAMETERS
6224 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006225
Arun Menon906de572013-06-18 17:01:40 -07006226 RETURN VALUE
6227 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006228
Arun Menon906de572013-06-18 17:01:40 -07006229 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006230OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6231{
6232#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006233 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006234 delete iDivXDrmDecrypt;
6235 iDivXDrmDecrypt=NULL;
6236 }
6237#endif //_ANDROID_
6238
Shalaj Jain286b0062013-02-21 20:35:48 -08006239 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07006240 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006241 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07006242 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006243 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07006244 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006245 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006246 }
6247
6248 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006249 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006250 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07006251 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
6252 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006253 }
6254#ifdef _ANDROID_ICS_
6255 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6256#endif
6257 }
6258
6259 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006260 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006261 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07006262 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
6263 if (m_inp_mem_ptr)
6264 free_input_buffer (i,&m_inp_mem_ptr[i]);
6265 else
6266 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006267 }
6268 }
6269 free_input_buffer_header();
6270 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07006271 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006272 free(h264_scratch.pBuffer);
6273 h264_scratch.pBuffer = NULL;
6274 }
6275
Arun Menon906de572013-06-18 17:01:40 -07006276 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006277 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07006278 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006279 }
6280
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006281 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006282 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006283 delete (m_frame_parser.mutils);
6284 m_frame_parser.mutils = NULL;
6285 }
6286
Arun Menon906de572013-06-18 17:01:40 -07006287 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006288 free(m_platform_list);
6289 m_platform_list = NULL;
6290 }
Arun Menon906de572013-06-18 17:01:40 -07006291 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006292 free(m_vendor_config.pData);
6293 m_vendor_config.pData = NULL;
6294 }
6295
6296 // Reset counters in mesg queues
6297 m_ftb_q.m_size=0;
6298 m_cmd_q.m_size=0;
6299 m_etb_q.m_size=0;
6300 m_ftb_q.m_read = m_ftb_q.m_write =0;
6301 m_cmd_q.m_read = m_cmd_q.m_write =0;
6302 m_etb_q.m_read = m_etb_q.m_write =0;
6303#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006304 if (m_debug_timestamp) {
6305 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006306 }
6307#endif
6308
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006309 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006310 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006311 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006312 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006313
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006314 if (m_debug.infile) {
6315 fclose(m_debug.infile);
6316 m_debug.infile = NULL;
6317 }
6318 if (m_debug.outfile) {
6319 fclose(m_debug.outfile);
6320 m_debug.outfile = NULL;
6321 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006322#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006323 if (outputExtradataFile)
6324 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006325#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006326 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006327 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006328}
6329
6330/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006331 FUNCTION
6332 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006333
Arun Menon906de572013-06-18 17:01:40 -07006334 DESCRIPTION
6335 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006336
Arun Menon906de572013-06-18 17:01:40 -07006337 PARAMETERS
6338 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006339
Arun Menon906de572013-06-18 17:01:40 -07006340 RETURN VALUE
6341 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006342
Arun Menon906de572013-06-18 17:01:40 -07006343 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006344OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006345 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6346 OMX_IN OMX_U32 port,
6347 OMX_IN OMX_PTR appData,
6348 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006349{
Arun Menon906de572013-06-18 17:01:40 -07006350 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6351 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6352 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006353
6354#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006355 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6356 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006357#else
Arun Menon906de572013-06-18 17:01:40 -07006358 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006359#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006360 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006361 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006362 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006363 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006364#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006365 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006366 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006367 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006368 }
6369 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6370 eglGetProcAddress("eglQueryImageKHR");
6371 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6372 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6373 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006374#else //with OMX test app
6375 struct temp_egl {
6376 int pmem_fd;
6377 int offset;
6378 };
6379 struct temp_egl *temp_egl_id = NULL;
6380 void * pmemPtr = (void *) eglImage;
6381 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006382 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006383 fd = temp_egl_id->pmem_fd;
6384 offset = temp_egl_id->offset;
6385 }
6386#endif
6387 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006388 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006389 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006390 }
6391 pmem_info.pmem_fd = (OMX_U32) fd;
6392 pmem_info.offset = (OMX_U32) offset;
6393 pmem_entry.entry = (void *) &pmem_info;
6394 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6395 pmem_list.entryList = &pmem_entry;
6396 pmem_list.nEntries = 1;
6397 ouput_egl_buffers = true;
6398 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6399 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6400 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006401 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006402 return OMX_ErrorInsufficientResources;
6403 }
6404 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006405}
6406
6407/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006408 FUNCTION
6409 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006410
Arun Menon906de572013-06-18 17:01:40 -07006411 DESCRIPTION
6412 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006413
Arun Menon906de572013-06-18 17:01:40 -07006414 PARAMETERS
6415 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006416
Arun Menon906de572013-06-18 17:01:40 -07006417 RETURN VALUE
6418 OMX Error None if everything is successful.
6419 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006420OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006421 OMX_OUT OMX_U8* role,
6422 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006423{
Arun Menon906de572013-06-18 17:01:40 -07006424 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006425
Arun Menon906de572013-06-18 17:01:40 -07006426 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6427 if ((0 == index) && role) {
6428 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006429 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006430 } else {
6431 eRet = OMX_ErrorNoMore;
6432 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006433 }
Arun Menon906de572013-06-18 17:01:40 -07006434 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6435 if ((0 == index) && role) {
6436 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006437 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006438 } else {
6439 eRet = OMX_ErrorNoMore;
6440 }
6441 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6442 if ((0 == index) && role) {
6443 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006444 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006445 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006446 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006447 eRet = OMX_ErrorNoMore;
6448 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006449 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006450
Arun Menon906de572013-06-18 17:01:40 -07006451 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6452 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6453 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006454
Shalaj Jain273b3e02012-06-22 19:08:03 -07006455 {
Arun Menon906de572013-06-18 17:01:40 -07006456 if ((0 == index) && role) {
6457 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006458 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006459 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006460 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006461 eRet = OMX_ErrorNoMore;
6462 }
6463 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6464 if ((0 == index) && role) {
6465 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006466 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006467 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006468 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006469 eRet = OMX_ErrorNoMore;
6470 }
6471 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6472 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6473 ) {
6474 if ((0 == index) && role) {
6475 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006476 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006477 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006478 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006479 eRet = OMX_ErrorNoMore;
6480 }
6481 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6482 if ((0 == index) && role) {
6483 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006484 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006485 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006486 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006487 eRet = OMX_ErrorNoMore;
6488 }
6489 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006490 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006491 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006492 }
Arun Menon906de572013-06-18 17:01:40 -07006493 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006494}
6495
6496
6497
6498
6499/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006500 FUNCTION
6501 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006502
Arun Menon906de572013-06-18 17:01:40 -07006503 DESCRIPTION
6504 Checks if entire buffer pool is allocated by IL Client or not.
6505 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006506
Arun Menon906de572013-06-18 17:01:40 -07006507 PARAMETERS
6508 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006509
Arun Menon906de572013-06-18 17:01:40 -07006510 RETURN VALUE
6511 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006512
Arun Menon906de572013-06-18 17:01:40 -07006513 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006514bool omx_vdec::allocate_done(void)
6515{
Arun Menon906de572013-06-18 17:01:40 -07006516 bool bRet = false;
6517 bool bRet_In = false;
6518 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006519
Arun Menon906de572013-06-18 17:01:40 -07006520 bRet_In = allocate_input_done();
6521 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006522
Arun Menon906de572013-06-18 17:01:40 -07006523 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006524 bRet = true;
6525 }
Arun Menon906de572013-06-18 17:01:40 -07006526
6527 return bRet;
6528}
6529/* ======================================================================
6530 FUNCTION
6531 omx_vdec::AllocateInputDone
6532
6533 DESCRIPTION
6534 Checks if I/P buffer pool is allocated by IL Client or not.
6535
6536 PARAMETERS
6537 None.
6538
6539 RETURN VALUE
6540 true/false.
6541
6542 ========================================================================== */
6543bool omx_vdec::allocate_input_done(void)
6544{
6545 bool bRet = false;
6546 unsigned i=0;
6547
6548 if (m_inp_mem_ptr == NULL) {
6549 return bRet;
6550 }
6551 if (m_inp_mem_ptr ) {
6552 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6553 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6554 break;
6555 }
6556 }
6557 }
6558 if (i == drv_ctx.ip_buf.actualcount) {
6559 bRet = true;
6560 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6561 }
6562 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6563 m_inp_bPopulated = OMX_TRUE;
6564 }
6565 return bRet;
6566}
6567/* ======================================================================
6568 FUNCTION
6569 omx_vdec::AllocateOutputDone
6570
6571 DESCRIPTION
6572 Checks if entire O/P buffer pool is allocated by IL Client or not.
6573
6574 PARAMETERS
6575 None.
6576
6577 RETURN VALUE
6578 true/false.
6579
6580 ========================================================================== */
6581bool omx_vdec::allocate_output_done(void)
6582{
6583 bool bRet = false;
6584 unsigned j=0;
6585
6586 if (m_out_mem_ptr == NULL) {
6587 return bRet;
6588 }
6589
6590 if (m_out_mem_ptr) {
6591 for (; j < drv_ctx.op_buf.actualcount; j++) {
6592 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6593 break;
6594 }
6595 }
6596 }
6597
6598 if (j == drv_ctx.op_buf.actualcount) {
6599 bRet = true;
6600 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6601 if (m_out_bEnabled)
6602 m_out_bPopulated = OMX_TRUE;
6603 }
6604
6605 return bRet;
6606}
6607
6608/* ======================================================================
6609 FUNCTION
6610 omx_vdec::ReleaseDone
6611
6612 DESCRIPTION
6613 Checks if IL client has released all the buffers.
6614
6615 PARAMETERS
6616 None.
6617
6618 RETURN VALUE
6619 true/false
6620
6621 ========================================================================== */
6622bool omx_vdec::release_done(void)
6623{
6624 bool bRet = false;
6625
6626 if (release_input_done()) {
6627 if (release_output_done()) {
6628 bRet = true;
6629 }
6630 }
6631 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006632}
6633
6634
6635/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006636 FUNCTION
6637 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006638
Arun Menon906de572013-06-18 17:01:40 -07006639 DESCRIPTION
6640 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006641
Arun Menon906de572013-06-18 17:01:40 -07006642 PARAMETERS
6643 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006644
Arun Menon906de572013-06-18 17:01:40 -07006645 RETURN VALUE
6646 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006647
Arun Menon906de572013-06-18 17:01:40 -07006648 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006649bool omx_vdec::release_output_done(void)
6650{
Arun Menon906de572013-06-18 17:01:40 -07006651 bool bRet = false;
6652 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006653
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006654 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006655 if (m_out_mem_ptr) {
6656 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6657 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6658 break;
6659 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006660 }
Arun Menon906de572013-06-18 17:01:40 -07006661 if (j == drv_ctx.op_buf.actualcount) {
6662 m_out_bm_count = 0;
6663 bRet = true;
6664 }
6665 } else {
6666 m_out_bm_count = 0;
6667 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006668 }
Arun Menon906de572013-06-18 17:01:40 -07006669 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006670}
6671/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006672 FUNCTION
6673 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006674
Arun Menon906de572013-06-18 17:01:40 -07006675 DESCRIPTION
6676 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006677
Arun Menon906de572013-06-18 17:01:40 -07006678 PARAMETERS
6679 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006680
Arun Menon906de572013-06-18 17:01:40 -07006681 RETURN VALUE
6682 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006683
Arun Menon906de572013-06-18 17:01:40 -07006684 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006685bool omx_vdec::release_input_done(void)
6686{
Arun Menon906de572013-06-18 17:01:40 -07006687 bool bRet = false;
6688 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006689
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006690 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006691 if (m_inp_mem_ptr) {
6692 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6693 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6694 break;
6695 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006696 }
Arun Menon906de572013-06-18 17:01:40 -07006697 if (j==drv_ctx.ip_buf.actualcount) {
6698 bRet = true;
6699 }
6700 } else {
6701 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006702 }
Arun Menon906de572013-06-18 17:01:40 -07006703 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006704}
6705
6706OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006707 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006708{
Arun Menon906de572013-06-18 17:01:40 -07006709 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306710 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006711 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006712 return OMX_ErrorBadParameter;
6713 } else if (output_flush_progress) {
6714 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6715 buffer->nFilledLen = 0;
6716 buffer->nTimeStamp = 0;
6717 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6718 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6719 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006720 }
6721
Arun Menon906de572013-06-18 17:01:40 -07006722 if (m_debug_extradata) {
6723 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006724 DEBUG_PRINT_HIGH("");
6725 DEBUG_PRINT_HIGH("***************************************************");
6726 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6727 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006728 }
6729
6730 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006731 DEBUG_PRINT_HIGH("");
6732 DEBUG_PRINT_HIGH("***************************************************");
6733 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6734 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006735 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006736 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006737
6738
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006739 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006740 buffer, buffer->pBuffer);
6741 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006742
Arun Menon906de572013-06-18 17:01:40 -07006743 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006744 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006745 if (!output_flush_progress)
6746 post_event((unsigned)NULL, (unsigned)NULL,
6747 OMX_COMPONENT_GENERATE_EOS_DONE);
6748
6749 if (psource_frame) {
6750 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6751 psource_frame = NULL;
6752 }
6753 if (pdest_frame) {
6754 pdest_frame->nFilledLen = 0;
6755 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6756 (unsigned)NULL);
6757 pdest_frame = NULL;
6758 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006759 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006760
Shalaj Jain273b3e02012-06-22 19:08:03 -07006761
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006762 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6763 DEBUG_PRINT_LOW("Processing extradata");
6764 handle_extradata(buffer);
6765 }
6766
Arun Menon906de572013-06-18 17:01:40 -07006767 /* For use buffer we need to copy the data */
6768 if (!output_flush_progress) {
6769 /* This is the error check for non-recoverable errros */
6770 bool is_duplicate_ts_valid = true;
6771 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006772
Arun Menon906de572013-06-18 17:01:40 -07006773 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6774 output_capability == V4L2_PIX_FMT_MPEG2 ||
6775 output_capability == V4L2_PIX_FMT_DIVX ||
6776 output_capability == V4L2_PIX_FMT_DIVX_311)
6777 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006778
Arun Menon906de572013-06-18 17:01:40 -07006779 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
Arun Menon7b6fd642014-02-13 16:48:36 -08006780 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
Arun Menon906de572013-06-18 17:01:40 -07006781 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306782 }
Arun Menon906de572013-06-18 17:01:40 -07006783 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306784
Arun Menon906de572013-06-18 17:01:40 -07006785 if (buffer->nFilledLen > 0) {
6786 time_stamp_dts.get_next_timestamp(buffer,
6787 is_interlaced && is_duplicate_ts_valid);
6788 if (m_debug_timestamp) {
6789 {
6790 OMX_TICKS expected_ts = 0;
6791 m_timestamp_list.pop_min_ts(expected_ts);
6792 if (is_interlaced && is_duplicate_ts_valid) {
6793 m_timestamp_list.pop_min_ts(expected_ts);
6794 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006795 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006796 buffer->nTimeStamp, expected_ts);
6797
6798 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006799 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006800 }
6801 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306802 }
Arun Menon906de572013-06-18 17:01:40 -07006803 } else {
Arun Menon906de572013-06-18 17:01:40 -07006804 time_stamp_dts.remove_time_stamp(
6805 buffer->nTimeStamp,
6806 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306807 }
Arun Menon906de572013-06-18 17:01:40 -07006808
6809
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006810 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006811
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006812 /* Since we're passing around handles, adjust nFilledLen and nAllocLen
6813 * to size of the handle. Do it _after_ handle_extradata() which
6814 * requires the respective sizes to be accurate. */
6815 if (dynamic_buf_mode) {
6816 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
6817 buffer->nFilledLen = buffer->nFilledLen ?
6818 sizeof(struct VideoDecoderOutputMetaData) : 0;
6819 }
6820
Arun Menon906de572013-06-18 17:01:40 -07006821 if (m_cb.FillBufferDone) {
6822 if (buffer->nFilledLen > 0) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006823 if (arbitrary_bytes)
Arun Menon906de572013-06-18 17:01:40 -07006824 adjust_timestamp(buffer->nTimeStamp);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006825 else
6826 set_frame_rate(buffer->nTimeStamp);
6827
Arun Menon906de572013-06-18 17:01:40 -07006828 if (perf_flag) {
6829 if (!proc_frms) {
6830 dec_time.stop();
6831 latency = dec_time.processing_time_us() - latency;
6832 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6833 dec_time.start();
6834 fps_metrics.start();
6835 }
6836 proc_frms++;
6837 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6838 OMX_U64 proc_time = 0;
6839 fps_metrics.stop();
6840 proc_time = fps_metrics.processing_time_us();
6841 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006842 proc_frms, (float)proc_time / 1e6,
6843 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006844 proc_frms = 0;
6845 }
6846 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006847
6848#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006849 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006850
Arun Menon906de572013-06-18 17:01:40 -07006851 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6852 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6853 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6854 buffer->nFilledLen + 3)&(~3));
6855 while (p_extra &&
6856 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006857 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006858 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6859 if (p_extra->eType == OMX_ExtraDataNone) {
6860 break;
6861 }
6862 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6863 }
6864 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006865#endif
Arun Menon906de572013-06-18 17:01:40 -07006866 }
6867 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6868 prev_ts = LLONG_MAX;
6869 rst_prev_ts = true;
6870 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006871
Arun Menon906de572013-06-18 17:01:40 -07006872 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6873 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6874 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006875 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006876 OMX_BUFFERHEADERTYPE *il_buffer;
6877 il_buffer = client_buffers.get_il_buf_hdr(buffer);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006878
vivek mehta79cff222014-01-22 12:17:07 -08006879 if (il_buffer && m_last_rendered_TS >= 0) {
6880 int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
Manikanta Kanamarlapudifb53b262014-01-20 16:12:47 +05306881 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
vivek mehta79cff222014-01-22 12:17:07 -08006882
6883 // Current frame can be send for rendering if
6884 // (a) current FPS is <= 60
6885 // (b) is the next frame after the frame with TS 0
6886 // (c) is the first frame after seek
6887 // (d) the delta TS b\w two consecutive frames is > 16 ms
6888 // (e) its TS is equal to previous frame TS
6889 // (f) if marked EOS
6890
6891 if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
6892 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
6893 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006894 m_last_rendered_TS = il_buffer->nTimeStamp;
vivek mehta79cff222014-01-22 12:17:07 -08006895 } else {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006896 //mark for droping
vivek mehtaa75c69f2014-01-10 21:50:37 -08006897 buffer->nFilledLen = 0;
vivek mehta79cff222014-01-22 12:17:07 -08006898 }
6899
6900 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%d)",
6901 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
6902 il_buffer->nTimeStamp,ts_delta);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006903 }
6904
vivek mehta79cff222014-01-22 12:17:07 -08006905 if (il_buffer) {
Arun Menon9230eb82014-02-11 19:19:02 -08006906 log_output_buffers(il_buffer);
6907 if (dynamic_buf_mode) {
6908 unsigned int nPortIndex = 0;
6909 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6910
6911 if (!secure_mode) {
6912 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6913 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6914 }
6915
6916 //Clear graphic buffer handles in dynamic mode
6917 native_buffer[nPortIndex].privatehandle = NULL;
6918 native_buffer[nPortIndex].nativehandle = NULL;
6919 }
Arun Menon906de572013-06-18 17:01:40 -07006920 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
vivek mehta79cff222014-01-22 12:17:07 -08006921 } else {
Arun Menon906de572013-06-18 17:01:40 -07006922 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6923 return OMX_ErrorBadParameter;
6924 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006925 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006926 } else {
6927 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006928 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006929
Praveen Chavancf924182013-12-06 23:16:23 -08006930#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306931 if (m_smoothstreaming_mode && m_out_mem_ptr) {
Praveen Chavancf924182013-12-06 23:16:23 -08006932 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6933 BufferDim_t dim;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306934 private_handle_t *private_handle = NULL;
Pushkaraj Patil065b5732014-11-26 11:08:02 +05306935 dim.sliceWidth = framesize.nWidth;
6936 dim.sliceHeight = framesize.nHeight;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306937 if (native_buffer[buf_index].privatehandle)
6938 private_handle = native_buffer[buf_index].privatehandle;
Praveen Chavancf924182013-12-06 23:16:23 -08006939 if (private_handle) {
6940 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6941 dim.sliceWidth, dim.sliceHeight);
6942 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6943 }
6944 }
6945#endif
6946
Arun Menon906de572013-06-18 17:01:40 -07006947 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006948}
6949
6950OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006951 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006952{
6953
Surajit Podderd2644d52013-08-28 17:59:06 +05306954 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006955 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006956 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006957 }
6958
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006959 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006960 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006961 pending_input_buffers--;
6962
Arun Menon906de572013-06-18 17:01:40 -07006963 if (arbitrary_bytes) {
6964 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006965 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006966 pdest_frame = buffer;
6967 buffer->nFilledLen = 0;
6968 buffer->nTimeStamp = LLONG_MAX;
6969 push_input_buffer (hComp);
6970 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006971 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006972 buffer->nFilledLen = 0;
6973 if (!m_input_free_q.insert_entry((unsigned)buffer,
6974 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006975 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006976 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006977 }
Arun Menon906de572013-06-18 17:01:40 -07006978 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006979 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006980 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006981 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6982 }
6983 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6984 }
6985 return OMX_ErrorNone;
6986}
6987
Shalaj Jain273b3e02012-06-22 19:08:03 -07006988int omx_vdec::async_message_process (void *context, void* message)
6989{
Arun Menon906de572013-06-18 17:01:40 -07006990 omx_vdec* omx = NULL;
6991 struct vdec_msginfo *vdec_msg = NULL;
6992 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6993 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6994 struct vdec_output_frameinfo *output_respbuf = NULL;
6995 int rc=1;
6996 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006997 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006998 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006999 }
Arun Menon906de572013-06-18 17:01:40 -07007000 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007001
Arun Menon906de572013-06-18 17:01:40 -07007002 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07007003
Arun Menon906de572013-06-18 17:01:40 -07007004 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007005
Arun Menon906de572013-06-18 17:01:40 -07007006 case VDEC_MSG_EVT_HW_ERROR:
7007 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7008 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7009 break;
7010
Deepak Verma24720fb2014-01-29 16:57:40 +05307011 case VDEC_MSG_EVT_HW_OVERLOAD:
7012 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7013 OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
7014 break;
7015
Arun Menon906de572013-06-18 17:01:40 -07007016 case VDEC_MSG_RESP_START_DONE:
7017 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7018 OMX_COMPONENT_GENERATE_START_DONE);
7019 break;
7020
7021 case VDEC_MSG_RESP_STOP_DONE:
7022 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7023 OMX_COMPONENT_GENERATE_STOP_DONE);
7024 break;
7025
7026 case VDEC_MSG_RESP_RESUME_DONE:
7027 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7028 OMX_COMPONENT_GENERATE_RESUME_DONE);
7029 break;
7030
7031 case VDEC_MSG_RESP_PAUSE_DONE:
7032 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7033 OMX_COMPONENT_GENERATE_PAUSE_DONE);
7034 break;
7035
7036 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
7037 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7038 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
7039 break;
7040 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
7041 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7042 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
7043 break;
7044 case VDEC_MSG_RESP_INPUT_FLUSHED:
7045 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
7046
7047 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
7048 vdec_msg->msgdata.input_frame_clientdata; */
7049
7050 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
7051 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
7052 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05307053 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07007054 omxhdr = NULL;
7055 vdec_msg->status_code = VDEC_S_EFATAL;
7056 }
7057 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
7058 DEBUG_PRINT_HIGH("Unsupported input");
7059 omx->omx_report_error ();
7060 }
7061 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
7062 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
7063 }
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307064 if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
7065 int pending_flush_waiters;
7066
7067 while (pending_flush_waiters = INT_MAX,
7068 sem_getvalue(&omx->m_safe_flush, &pending_flush_waiters),
7069 /* 0 == there /are/ waiters depending on POSIX implementation */
7070 pending_flush_waiters <= 0 ) {
7071 DEBUG_PRINT_LOW("sem post for %d EBD of CODEC CONFIG buffer",
7072 omx->m_queued_codec_config_count);
7073 sem_post(&omx->m_safe_flush);
7074 }
Pushkaraj Patil20bd6bf2014-12-22 19:33:08 +05307075 DEBUG_PRINT_LOW("Reset codec_config buffer counter");
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307076 android_atomic_and(0, &omx->m_queued_codec_config_count); /* no clearer way to set to 0 */
7077 }
7078
Arun Menon906de572013-06-18 17:01:40 -07007079 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
7080 OMX_COMPONENT_GENERATE_EBD);
7081 break;
7082 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
7083 int64_t *timestamp;
7084 timestamp = (int64_t *) malloc(sizeof(int64_t));
7085 if (timestamp) {
7086 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
7087 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
7088 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007089 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07007090 vdec_msg->msgdata.output_frame.time_stamp);
7091 }
7092 break;
7093 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
7094 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
7095
7096 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
7097 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307098
7099 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 -07007100 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307101 vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
7102 (unsigned int)vdec_msg->msgdata.output_frame.len,
7103 vdec_msg->msgdata.output_frame.framesize.left,
7104 vdec_msg->msgdata.output_frame.framesize.top,
7105 vdec_msg->msgdata.output_frame.framesize.right,
7106 vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07007107
7108 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05307109 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07007110 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05307111 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307112
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07007113 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
Arun Menon906de572013-06-18 17:01:40 -07007114 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
7115 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
7116 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
7117 omxhdr->nFlags = 0;
7118
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07007119 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07007120 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
7121 //rc = -1;
7122 }
7123 if (omxhdr->nFilledLen) {
7124 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
7125 }
7126 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
7127 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
7128 } else {
7129 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
7130 }
7131 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
7132 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7133 }
7134 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
7135 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
7136 }
Arun Menon7b6fd642014-02-13 16:48:36 -08007137
7138 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
7139 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
7140 }
7141
Arun Menonbdb80b02013-08-12 17:45:54 -07007142 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07007143 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07007144 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
7145 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
7146 }
Arun Menonbdb80b02013-08-12 17:45:54 -07007147 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
7148 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
7149 omxhdr->nOffset);
7150 }
Arun Menon906de572013-06-18 17:01:40 -07007151 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
7152 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07007153 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07007154 omx->time_stamp_dts.remove_time_stamp(
7155 omxhdr->nTimeStamp,
7156 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
7157 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07007158 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
7159 OMX_COMPONENT_GENERATE_FTB);
7160 break;
7161 }
7162 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
7163 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7164 }
7165 vdec_msg->msgdata.output_frame.bufferaddr =
7166 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307167
7168 /* Post event if resolution OR crop changed */
7169 /* filled length will be changed if resolution changed */
7170 /* Crop parameters can be changed even without resolution change */
7171 if (omxhdr->nFilledLen
7172 && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
7173 || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
7174 || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
7175 || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05307176 || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
7177 || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
7178 || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307179
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05307180 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",
7181 omx->prev_n_filled_len,
7182 omx->drv_ctx.video_resolution.frame_width,
7183 omx->drv_ctx.video_resolution.frame_height,
7184 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
7185 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
7186 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
7187 vdec_msg->msgdata.output_frame.picsize.frame_height,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307188 vdec_msg->msgdata.output_frame.framesize.left,
7189 vdec_msg->msgdata.output_frame.framesize.top,
7190 vdec_msg->msgdata.output_frame.framesize.right,
7191 vdec_msg->msgdata.output_frame.framesize.bottom);
7192
Maheshwar Ajja0f840ce2014-09-29 16:53:42 +05307193 omx->drv_ctx.video_resolution.frame_width =
7194 vdec_msg->msgdata.output_frame.picsize.frame_width;
7195 omx->drv_ctx.video_resolution.frame_height =
7196 vdec_msg->msgdata.output_frame.picsize.frame_height;
7197
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307198 memcpy(&omx->drv_ctx.frame_size,
7199 &vdec_msg->msgdata.output_frame.framesize,
7200 sizeof(struct vdec_framesize));
7201
7202 omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
7203 OMX_IndexConfigCommonOutputCrop,
7204 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Arun Menon906de572013-06-18 17:01:40 -07007205 }
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307206
Arun Menon906de572013-06-18 17:01:40 -07007207 if (omxhdr->nFilledLen)
7208 omx->prev_n_filled_len = omxhdr->nFilledLen;
7209
7210 output_respbuf = (struct vdec_output_frameinfo *)\
7211 omxhdr->pOutputPortPrivate;
7212 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7213 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307214
Arun Menon906de572013-06-18 17:01:40 -07007215 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
7216 output_respbuf->pic_type = PICTURE_TYPE_I;
7217 }
7218 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
7219 output_respbuf->pic_type = PICTURE_TYPE_P;
7220 }
7221 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7222 output_respbuf->pic_type = PICTURE_TYPE_B;
7223 }
7224
7225 if (omx->output_use_buffer)
7226 memcpy ( omxhdr->pBuffer, (void *)
7227 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7228 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7229 vdec_msg->msgdata.output_frame.len);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307230 } else {
7231 DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
7232 (unsigned int)vdec_msg->msgdata.output_frame.len,
7233 omxhdr->nAllocLen, omx->prev_n_filled_len);
Arun Menon906de572013-06-18 17:01:40 -07007234 omxhdr->nFilledLen = 0;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307235 }
7236
Arun Menon906de572013-06-18 17:01:40 -07007237 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7238 OMX_COMPONENT_GENERATE_FBD);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307239
7240 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07007241 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7242 OMX_COMPONENT_GENERATE_EOS_DONE);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307243 } else {
Arun Menon906de572013-06-18 17:01:40 -07007244 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7245 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307246 }
Arun Menon906de572013-06-18 17:01:40 -07007247 break;
7248 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007249 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07007250 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7251 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7252 break;
7253 default:
7254 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007255 }
Arun Menon906de572013-06-18 17:01:40 -07007256 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007257}
7258
7259OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07007260 OMX_HANDLETYPE hComp,
7261 OMX_BUFFERHEADERTYPE *buffer
7262 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07007263{
Arun Menon906de572013-06-18 17:01:40 -07007264 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007265 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007266
Arun Menon906de572013-06-18 17:01:40 -07007267 if (buffer == NULL) {
7268 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007269 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007270 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7271 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007272 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
7273
7274 /* return zero length and not an EOS buffer */
7275 /* return buffer if input flush in progress */
7276 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7277 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007278 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07007279 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7280 return OMX_ErrorNone;
7281 }
7282
7283 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007284 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007285 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007286 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07007287 push_input_buffer (hComp);
7288 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007289 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07007290 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7291 (unsigned)NULL)) {
7292 return OMX_ErrorBadParameter;
7293 }
7294 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007295
Sowmya Pandiri302f5ab2014-04-03 13:41:03 -07007296 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
7297 codec_config_flag = false;
7298 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007299
Arun Menon906de572013-06-18 17:01:40 -07007300 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007301}
7302
7303OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7304{
Arun Menon906de572013-06-18 17:01:40 -07007305 unsigned address,p2,id;
7306 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007307
Arun Menon906de572013-06-18 17:01:40 -07007308 if (pdest_frame == NULL || psource_frame == NULL) {
7309 /*Check if we have a destination buffer*/
7310 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007311 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007312 if (m_input_free_q.m_size) {
7313 m_input_free_q.pop_entry(&address,&p2,&id);
7314 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7315 pdest_frame->nFilledLen = 0;
7316 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007317 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007318 }
7319 }
7320
7321 /*Check if we have a destination buffer*/
7322 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007323 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007324 if (m_input_pending_q.m_size) {
7325 m_input_pending_q.pop_entry(&address,&p2,&id);
7326 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007327 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007328 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007329 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007330 psource_frame->nFlags,psource_frame->nFilledLen);
7331
7332 }
7333 }
7334
Shalaj Jain273b3e02012-06-22 19:08:03 -07007335 }
7336
Arun Menon906de572013-06-18 17:01:40 -07007337 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7338 switch (codec_type_parse) {
7339 case CODEC_TYPE_MPEG4:
7340 case CODEC_TYPE_H263:
7341 case CODEC_TYPE_MPEG2:
7342 ret = push_input_sc_codec(hComp);
7343 break;
7344 case CODEC_TYPE_H264:
7345 ret = push_input_h264(hComp);
7346 break;
7347 case CODEC_TYPE_VC1:
7348 ret = push_input_vc1(hComp);
7349 break;
7350 default:
7351 break;
7352 }
7353 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007354 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007355 omx_report_error ();
7356 break;
7357 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007358 }
7359
Arun Menon906de572013-06-18 17:01:40 -07007360 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007361}
7362
7363OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7364{
Arun Menon906de572013-06-18 17:01:40 -07007365 OMX_U32 partial_frame = 1;
7366 OMX_BOOL generate_ebd = OMX_TRUE;
7367 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007368
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007369 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007370 psource_frame,psource_frame->nTimeStamp);
7371 if (m_frame_parser.parse_sc_frame(psource_frame,
7372 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007373 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007374 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007375 }
Arun Menon906de572013-06-18 17:01:40 -07007376
7377 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007378 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007379 pdest_frame->nFilledLen,psource_frame,frame_count);
7380
7381
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007382 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007383 /*First Parsed buffer will have only header Hence skip*/
7384 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007385 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007386
7387 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7388 codec_type_parse == CODEC_TYPE_DIVX) {
7389 mp4StreamType psBits;
7390 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7391 psBits.numBytes = pdest_frame->nFilledLen;
7392 mp4_headerparser.parseHeader(&psBits);
7393 }
7394
7395 frame_count++;
7396 } else {
7397 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7398 if (pdest_frame->nFilledLen) {
7399 /*Push the frame to the Decoder*/
7400 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7401 return OMX_ErrorBadParameter;
7402 }
7403 frame_count++;
7404 pdest_frame = NULL;
7405
7406 if (m_input_free_q.m_size) {
7407 m_input_free_q.pop_entry(&address,&p2,&id);
7408 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7409 pdest_frame->nFilledLen = 0;
7410 }
7411 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007412 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007413 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7414 (unsigned)NULL);
7415 pdest_frame = NULL;
7416 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007417 }
Arun Menon906de572013-06-18 17:01:40 -07007418 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007419 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007420 /*Check if Destination Buffer is full*/
7421 if (pdest_frame->nAllocLen ==
7422 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007423 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007424 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007425 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007426 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007427
Arun Menon906de572013-06-18 17:01:40 -07007428 if (psource_frame->nFilledLen == 0) {
7429 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7430 if (pdest_frame) {
7431 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007432 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007433 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007434 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007435 pdest_frame->nFilledLen,frame_count++);
7436 /*Push the frame to the Decoder*/
7437 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7438 return OMX_ErrorBadParameter;
7439 }
7440 frame_count++;
7441 pdest_frame = NULL;
7442 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007443 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007444 generate_ebd = OMX_FALSE;
7445 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007446 }
Arun Menon906de572013-06-18 17:01:40 -07007447 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007448 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007449 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7450 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007451
Arun Menon906de572013-06-18 17:01:40 -07007452 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007453 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007454 m_input_pending_q.pop_entry(&address,&p2,&id);
7455 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007456 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007457 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007458 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007459 psource_frame->nFlags,psource_frame->nFilledLen);
7460 }
7461 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007462 }
Arun Menon906de572013-06-18 17:01:40 -07007463 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007464}
7465
7466OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7467{
Arun Menon906de572013-06-18 17:01:40 -07007468 OMX_U32 partial_frame = 1;
7469 unsigned address = 0, p2 = 0, id = 0;
7470 OMX_BOOL isNewFrame = OMX_FALSE;
7471 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007472
Arun Menon906de572013-06-18 17:01:40 -07007473 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007474 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007475 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007476 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007477 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007478 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007479 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007480 if (h264_scratch.nFilledLen && look_ahead_nal) {
7481 look_ahead_nal = false;
7482 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7483 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007484 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7485 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7486 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007487 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007488 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007489 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007490 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007491 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007492 }
Arun Menon906de572013-06-18 17:01:40 -07007493 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007494
7495 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7496 in EOS flag getting associated with the destination
7497 */
7498 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7499 pdest_frame->nFilledLen) {
7500 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7501 generate_ebd = OMX_FALSE;
7502 }
7503
Arun Menon906de572013-06-18 17:01:40 -07007504 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007505 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007506 if (m_frame_parser.parse_sc_frame(psource_frame,
7507 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007508 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007509 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007510 }
Arun Menon906de572013-06-18 17:01:40 -07007511 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007512 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007513 if (m_frame_parser.parse_h264_nallength(psource_frame,
7514 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007515 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007516 return OMX_ErrorBadParameter;
7517 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007518 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007519
Arun Menon906de572013-06-18 17:01:40 -07007520 if (partial_frame == 0) {
7521 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007522 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007523 nal_count++;
7524 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7525 h264_scratch.nFlags = psource_frame->nFlags;
7526 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007527 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007528 if (h264_scratch.nFilledLen) {
7529 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7530 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007531#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007532 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7533 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7534 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7535 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7536 // If timeinfo is present frame info from SEI is already processed
7537 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7538 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007539#endif
Arun Menon906de572013-06-18 17:01:40 -07007540 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7541 nal_count++;
7542 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7543 pdest_frame->nTimeStamp = h264_last_au_ts;
7544 pdest_frame->nFlags = h264_last_au_flags;
7545#ifdef PANSCAN_HDLR
7546 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7547 h264_parser->update_panscan_data(h264_last_au_ts);
7548#endif
7549 }
7550 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7551 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7552 h264_last_au_ts = h264_scratch.nTimeStamp;
7553 h264_last_au_flags = h264_scratch.nFlags;
7554#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7555 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7556 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7557 if (!VALID_TS(h264_last_au_ts))
7558 h264_last_au_ts = ts_in_sei;
7559 }
7560#endif
7561 } else
7562 h264_last_au_ts = LLONG_MAX;
7563 }
7564
7565 if (!isNewFrame) {
7566 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7567 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007568 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007569 h264_scratch.nFilledLen);
7570 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7571 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7572 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7573 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7574 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7575 h264_scratch.nFilledLen = 0;
7576 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007577 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007578 return OMX_ErrorBadParameter;
7579 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007580 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007581 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007582 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007583 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007584 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007585 pdest_frame->nFilledLen,frame_count++);
7586
7587 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007588 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007589 look_ahead_nal = false;
7590 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7591 h264_scratch.nFilledLen) {
7592 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7593 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7594 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7595 h264_scratch.nFilledLen = 0;
7596 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007597 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007598 return OMX_ErrorBadParameter;
7599 }
7600 } else {
7601 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007602 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007603 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7604 }
7605 /*Push the frame to the Decoder*/
7606 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7607 return OMX_ErrorBadParameter;
7608 }
7609 //frame_count++;
7610 pdest_frame = NULL;
7611 if (m_input_free_q.m_size) {
7612 m_input_free_q.pop_entry(&address,&p2,&id);
7613 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007614 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007615 pdest_frame->nFilledLen = 0;
7616 pdest_frame->nFlags = 0;
7617 pdest_frame->nTimeStamp = LLONG_MAX;
7618 }
7619 }
7620 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007621 }
Arun Menon906de572013-06-18 17:01:40 -07007622 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007623 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007624 /*Check if Destination Buffer is full*/
7625 if (h264_scratch.nAllocLen ==
7626 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007627 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007628 return OMX_ErrorStreamCorrupt;
7629 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007630 }
Arun Menon906de572013-06-18 17:01:40 -07007631
7632 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007633 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007634
7635 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7636 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007637 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007638 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7639 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007640 if(pdest_frame->nFilledLen == 0) {
7641 /* No residual frame from before, send whatever
7642 * we have left */
7643 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7644 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7645 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7646 h264_scratch.nFilledLen = 0;
7647 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7648 } else {
7649 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7650 if(!isNewFrame) {
7651 /* Have a residual frame, but we know that the
7652 * AU in this frame is belonging to whatever
7653 * frame we had left over. So append it */
7654 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7655 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7656 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7657 h264_scratch.nFilledLen = 0;
Balamurugan Alagarsamyefde3832014-09-22 19:52:20 +05307658 if (h264_last_au_ts != LLONG_MAX)
7659 pdest_frame->nTimeStamp = h264_last_au_ts;
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007660 } else {
7661 /* Completely new frame, let's just push what
7662 * we have now. The resulting EBD would trigger
7663 * another push */
7664 generate_ebd = OMX_FALSE;
7665 pdest_frame->nTimeStamp = h264_last_au_ts;
7666 h264_last_au_ts = h264_scratch.nTimeStamp;
7667 }
7668 }
Arun Menon906de572013-06-18 17:01:40 -07007669 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007670 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007671 return OMX_ErrorBadParameter;
7672 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007673
7674 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7675 if(generate_ebd == OMX_TRUE) {
7676 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7677 }
Arun Menon906de572013-06-18 17:01:40 -07007678
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007679 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007680 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007681 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007682#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7683 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7684 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7685 if (!VALID_TS(pdest_frame->nTimeStamp))
7686 pdest_frame->nTimeStamp = ts_in_sei;
7687 }
7688#endif
7689 /*Push the frame to the Decoder*/
7690 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7691 return OMX_ErrorBadParameter;
7692 }
7693 frame_count++;
7694 pdest_frame = NULL;
7695 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007696 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007697 pdest_frame,h264_scratch.nFilledLen);
7698 generate_ebd = OMX_FALSE;
7699 }
7700 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007701 }
Arun Menon906de572013-06-18 17:01:40 -07007702 if (generate_ebd && !psource_frame->nFilledLen) {
7703 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7704 psource_frame = NULL;
7705 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007706 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007707 m_input_pending_q.pop_entry(&address,&p2,&id);
7708 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007709 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007710 psource_frame->nFlags,psource_frame->nFilledLen);
7711 }
7712 }
7713 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007714}
7715
7716OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7717{
7718 OMX_U8 *buf, *pdest;
7719 OMX_U32 partial_frame = 1;
7720 OMX_U32 buf_len, dest_len;
7721
Arun Menon906de572013-06-18 17:01:40 -07007722 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007723 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007724 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007725 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007726 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007727 buf = psource_frame->pBuffer;
7728 buf_len = psource_frame->nFilledLen;
7729
7730 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007731 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007732 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007733 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007734 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007735 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007736 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007737 return OMX_ErrorStreamCorrupt;
7738 }
Arun Menon906de572013-06-18 17:01:40 -07007739 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007740 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7741 pdest_frame->nOffset;
7742 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007743 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007744
Arun Menon906de572013-06-18 17:01:40 -07007745 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007746 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007747 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007748 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007749 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7750 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7751 }
7752 }
7753 }
7754
Arun Menon906de572013-06-18 17:01:40 -07007755 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007756 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007757 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007758 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007759 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007760 return OMX_ErrorBadParameter;
7761 }
Arun Menon906de572013-06-18 17:01:40 -07007762 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007763
7764 case VC1_SP_MP_RCV:
7765 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007766 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007767 return OMX_ErrorBadParameter;
7768 }
7769 return OMX_ErrorNone;
7770}
7771
David Ng38e2d232013-03-15 20:05:58 -07007772#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007773bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007774 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007775{
Arun Menon906de572013-06-18 17:01:40 -07007776 struct pmem_allocation allocation;
7777 allocation.size = buffer_size;
7778 allocation.align = clip2(alignment);
7779 if (allocation.align < 4096) {
7780 allocation.align = 4096;
7781 }
7782 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007783 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007784 allocation.align, allocation.size);
7785 return false;
7786 }
7787 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007788}
David Ng38e2d232013-03-15 20:05:58 -07007789#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007790#ifdef USE_ION
7791int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007792 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7793 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007794{
Arun Menon906de572013-06-18 17:01:40 -07007795 int fd = -EINVAL;
7796 int rc = -EINVAL;
7797 int ion_dev_flag;
7798 struct vdec_ion ion_buf_info;
7799 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007800 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007801 return -EINVAL;
7802 }
7803 ion_dev_flag = O_RDONLY;
7804 fd = open (MEM_DEVICE, ion_dev_flag);
7805 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007806 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007807 return fd;
7808 }
7809 alloc_data->flags = 0;
7810 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7811 alloc_data->flags |= ION_FLAG_CACHED;
7812 }
7813 alloc_data->len = buffer_size;
7814 alloc_data->align = clip2(alignment);
7815 if (alloc_data->align < 4096) {
7816 alloc_data->align = 4096;
7817 }
7818 if ((secure_mode) && (flag & ION_SECURE))
7819 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007820
Arun Menon906de572013-06-18 17:01:40 -07007821 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307822 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007823 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7824 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7825 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007826 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007827 alloc_data->handle = NULL;
7828 close(fd);
7829 fd = -ENOMEM;
7830 return fd;
7831 }
7832 fd_data->handle = alloc_data->handle;
7833 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7834 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007835 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007836 ion_buf_info.ion_alloc_data = *alloc_data;
7837 ion_buf_info.ion_device_fd = fd;
7838 ion_buf_info.fd_ion_data = *fd_data;
7839 free_ion_memory(&ion_buf_info);
7840 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007841 fd = -ENOMEM;
7842 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007843
Arun Menon906de572013-06-18 17:01:40 -07007844 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007845}
7846
Arun Menon906de572013-06-18 17:01:40 -07007847void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7848{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007849
Arun Menon906de572013-06-18 17:01:40 -07007850 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007851 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007852 return;
7853 }
7854 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7855 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007856 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007857 }
7858 close(buf_ion_info->ion_device_fd);
7859 buf_ion_info->ion_device_fd = -1;
7860 buf_ion_info->ion_alloc_data.handle = NULL;
7861 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007862}
7863#endif
7864void omx_vdec::free_output_buffer_header()
7865{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007866 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007867 output_use_buffer = false;
7868 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007869
Arun Menon906de572013-06-18 17:01:40 -07007870 if (m_out_mem_ptr) {
7871 free (m_out_mem_ptr);
7872 m_out_mem_ptr = NULL;
7873 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007874
Arun Menon906de572013-06-18 17:01:40 -07007875 if (m_platform_list) {
7876 free(m_platform_list);
7877 m_platform_list = NULL;
7878 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007879
Arun Menon906de572013-06-18 17:01:40 -07007880 if (drv_ctx.ptr_respbuffer) {
7881 free (drv_ctx.ptr_respbuffer);
7882 drv_ctx.ptr_respbuffer = NULL;
7883 }
7884 if (drv_ctx.ptr_outputbuffer) {
7885 free (drv_ctx.ptr_outputbuffer);
7886 drv_ctx.ptr_outputbuffer = NULL;
7887 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007888#ifdef USE_ION
7889 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007890 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007891 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007892 drv_ctx.op_buf_ion_info = NULL;
7893 }
7894#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007895 if (out_dynamic_list) {
7896 free(out_dynamic_list);
7897 out_dynamic_list = NULL;
7898 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007899}
7900
7901void omx_vdec::free_input_buffer_header()
7902{
7903 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007904 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007905 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007906 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007907 free (m_inp_heap_ptr);
7908 m_inp_heap_ptr = NULL;
7909 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007910
Arun Menon906de572013-06-18 17:01:40 -07007911 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007912 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007913 free (m_phdr_pmem_ptr);
7914 m_phdr_pmem_ptr = NULL;
7915 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007916 }
Arun Menon906de572013-06-18 17:01:40 -07007917 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007918 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007919 free (m_inp_mem_ptr);
7920 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007921 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007922 /* We just freed all the buffer headers, every thing in m_input_free_q,
7923 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007924 while (m_input_free_q.m_size) {
7925 unsigned address, p2, id;
7926 m_input_free_q.pop_entry(&address, &p2, &id);
7927 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007928 while (m_input_pending_q.m_size) {
7929 unsigned address, p2, id;
7930 m_input_pending_q.pop_entry(&address, &p2, &id);
7931 }
7932 pdest_frame = NULL;
7933 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007934 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007935 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007936 free (drv_ctx.ptr_inputbuffer);
7937 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007938 }
7939#ifdef USE_ION
7940 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007941 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007942 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007943 drv_ctx.ip_buf_ion_info = NULL;
7944 }
7945#endif
7946}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007947
7948int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007949{
Arun Menon906de572013-06-18 17:01:40 -07007950 enum v4l2_buf_type btype;
7951 int rc = 0;
7952 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007953
Arun Menon906de572013-06-18 17:01:40 -07007954 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7955 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7956 v4l2_port = OUTPUT_PORT;
7957 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7958 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7959 v4l2_port = CAPTURE_PORT;
7960 } else if (port == OMX_ALL) {
7961 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7962 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007963
Arun Menon906de572013-06-18 17:01:40 -07007964 if (!rc_input)
7965 return rc_input;
7966 else
7967 return rc_output;
7968 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007969
Arun Menon906de572013-06-18 17:01:40 -07007970 if (!streaming[v4l2_port]) {
7971 // already streamed off, warn and move on
7972 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7973 " which is already streamed off", v4l2_port);
7974 return 0;
7975 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007976
Arun Menon906de572013-06-18 17:01:40 -07007977 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007978
Arun Menon906de572013-06-18 17:01:40 -07007979 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7980 if (rc) {
7981 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007982 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007983 } else {
7984 streaming[v4l2_port] = false;
7985 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007986
Arun Menon906de572013-06-18 17:01:40 -07007987 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007988}
7989
7990OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7991{
Arun Menon906de572013-06-18 17:01:40 -07007992 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7993 struct v4l2_requestbuffers bufreq;
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07007994 unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05307995 unsigned int final_extra_data_size = 0;
Arun Menon906de572013-06-18 17:01:40 -07007996 struct v4l2_format fmt;
7997 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007998 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007999 buffer_prop->actualcount, buffer_prop->buffer_size);
8000 bufreq.memory = V4L2_MEMORY_USERPTR;
8001 bufreq.count = 1;
8002 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8003 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8004 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8005 fmt.fmt.pix_mp.pixelformat = output_capability;
8006 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8007 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8008 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8009 fmt.fmt.pix_mp.pixelformat = capture_capability;
8010 } else {
8011 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008012 }
Arun Menon906de572013-06-18 17:01:40 -07008013 if (eRet==OMX_ErrorNone) {
8014 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008015 }
Arun Menon906de572013-06-18 17:01:40 -07008016 if (ret) {
8017 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8018 /*TODO: How to handle this case */
8019 eRet = OMX_ErrorInsufficientResources;
8020 return eRet;
8021 } else {
8022 buffer_prop->actualcount = bufreq.count;
8023 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008024 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008025 }
Arun Menon906de572013-06-18 17:01:40 -07008026 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
8027 buffer_prop->actualcount, buffer_prop->buffer_size);
8028
8029 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8030 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
8031
8032 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8033
8034 update_resolution(fmt.fmt.pix_mp.width,
8035 fmt.fmt.pix_mp.height,
8036 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
8037 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
8038 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
8039 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008040 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07008041
8042 if (ret) {
8043 /*TODO: How to handle this case */
8044 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8045 eRet = OMX_ErrorInsufficientResources;
8046 } else {
8047 int extra_idx = 0;
8048
8049 eRet = is_video_session_supported();
8050 if (eRet)
8051 return eRet;
8052
8053 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
8054 buf_size = buffer_prop->buffer_size;
8055 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
8056 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
8057 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
8058 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008059 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07008060 return OMX_ErrorBadParameter;
8061 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008062
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07008063 default_extra_data_size = VENUS_EXTRADATA_SIZE(
8064 drv_ctx.video_resolution.frame_height,
8065 drv_ctx.video_resolution.frame_width);
8066 final_extra_data_size = extra_data_size > default_extra_data_size ?
8067 extra_data_size : default_extra_data_size;
8068
8069 final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
8070 (~(buffer_prop->alignment - 1));
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07008071
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308072 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07008073 drv_ctx.extradata_info.count = buffer_prop->actualcount;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308074 drv_ctx.extradata_info.buffer_size = final_extra_data_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308075 if (!secure_mode)
8076 buf_size += final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07008077 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8078 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
8079 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008080 if (extra_data_size)
8081 DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%d)",
8082 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
8083
Arun Menon906de572013-06-18 17:01:40 -07008084 if (in_reconfig) // BufReq will be set to driver when port is disabled
8085 buffer_prop->buffer_size = buf_size;
8086 else if (buf_size != buffer_prop->buffer_size) {
8087 buffer_prop->buffer_size = buf_size;
8088 eRet = set_buffer_req(buffer_prop);
8089 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008090 }
Arun Menon906de572013-06-18 17:01:40 -07008091 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
8092 buffer_prop->actualcount, buffer_prop->buffer_size);
8093 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008094}
8095
8096OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
8097{
Arun Menon906de572013-06-18 17:01:40 -07008098 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8099 unsigned buf_size = 0;
8100 struct v4l2_format fmt;
8101 struct v4l2_requestbuffers bufreq;
8102 int ret;
8103 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
8104 buffer_prop->actualcount, buffer_prop->buffer_size);
8105 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8106 if (buf_size != buffer_prop->buffer_size) {
8107 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
8108 buffer_prop->buffer_size, buf_size);
8109 eRet = OMX_ErrorBadParameter;
8110 } else {
8111 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8112 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008113
Arun Menon906de572013-06-18 17:01:40 -07008114 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8115 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8116 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07008117 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07008118 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8119 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8120 fmt.fmt.pix_mp.pixelformat = capture_capability;
8121 } else {
8122 eRet = OMX_ErrorBadParameter;
8123 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008124
Arun Menon906de572013-06-18 17:01:40 -07008125 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
8126 if (ret) {
8127 /*TODO: How to handle this case */
8128 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
8129 eRet = OMX_ErrorInsufficientResources;
8130 }
8131
8132 bufreq.memory = V4L2_MEMORY_USERPTR;
8133 bufreq.count = buffer_prop->actualcount;
8134 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8135 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8136 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8137 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8138 } else {
8139 eRet = OMX_ErrorBadParameter;
8140 }
8141
8142 if (eRet==OMX_ErrorNone) {
8143 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8144 }
8145
8146 if (ret) {
8147 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8148 /*TODO: How to handle this case */
8149 eRet = OMX_ErrorInsufficientResources;
8150 } else if (bufreq.count < buffer_prop->actualcount) {
8151 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8152 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8153 buffer_prop->actualcount, bufreq.count);
8154 eRet = OMX_ErrorInsufficientResources;
8155 } else {
8156 if (!client_buffers.update_buffer_req()) {
8157 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8158 eRet = OMX_ErrorInsufficientResources;
8159 }
8160 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008161 }
Arun Menon906de572013-06-18 17:01:40 -07008162 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008163}
8164
Shalaj Jain273b3e02012-06-22 19:08:03 -07008165OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8166{
Arun Menon906de572013-06-18 17:01:40 -07008167 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8168 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008169}
8170
8171OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8172{
Arun Menon906de572013-06-18 17:01:40 -07008173 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308174 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07008175 if (!portDefn) {
8176 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008177 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008178 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07008179 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8180 portDefn->nSize = sizeof(portDefn);
8181 portDefn->eDomain = OMX_PortDomainVideo;
8182 if (drv_ctx.frame_rate.fps_denominator > 0)
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08008183 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
8184 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
Arun Menon906de572013-06-18 17:01:40 -07008185 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008186 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07008187 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008188 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308189 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Arun Menon906de572013-06-18 17:01:40 -07008190 if (0 == portDefn->nPortIndex) {
8191 portDefn->eDir = OMX_DirInput;
8192 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8193 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8194 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8195 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8196 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8197 portDefn->bEnabled = m_inp_bEnabled;
8198 portDefn->bPopulated = m_inp_bPopulated;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308199
8200 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8201 fmt.fmt.pix_mp.pixelformat = output_capability;
Arun Menon906de572013-06-18 17:01:40 -07008202 } else if (1 == portDefn->nPortIndex) {
8203 unsigned int buf_size = 0;
8204 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008205 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07008206 return OMX_ErrorHardware;
8207 }
8208 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008209 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07008210 return OMX_ErrorHardware;
8211 }
8212 portDefn->nBufferSize = buf_size;
8213 portDefn->eDir = OMX_DirOutput;
8214 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8215 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
8216 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8217 portDefn->bEnabled = m_out_bEnabled;
8218 portDefn->bPopulated = m_out_bPopulated;
8219 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008220 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07008221 return OMX_ErrorHardware;
8222 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308223 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8224 fmt.fmt.pix_mp.pixelformat = capture_capability;
Arun Menon906de572013-06-18 17:01:40 -07008225 } else {
8226 portDefn->eDir = OMX_DirMax;
8227 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8228 (int)portDefn->nPortIndex);
8229 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008230 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308231 if (is_down_scalar_enabled) {
8232 int ret = 0;
8233 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8234 if (ret) {
8235 DEBUG_PRINT_ERROR("update_portdef : Error in getting port resolution");
8236 return OMX_ErrorHardware;
8237 } else {
8238 portDefn->format.video.nFrameWidth = fmt.fmt.pix_mp.width;
8239 portDefn->format.video.nFrameHeight = fmt.fmt.pix_mp.height;
8240 portDefn->format.video.nStride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
8241 portDefn->format.video.nSliceHeight = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
8242 }
8243 } else {
8244 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8245 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8246 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8247 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
8248 }
8249
Praveen Chavandb7776f2014-02-06 18:17:25 -08008250 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
8251 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308252 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
8253 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
8254 }
8255 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
8256 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
8257 portDefn->nPortIndex,
8258 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07008259 portDefn->format.video.nFrameHeight,
8260 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308261 portDefn->format.video.nSliceHeight,
8262 portDefn->format.video.eColorFormat,
8263 portDefn->nBufferSize,
8264 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008265
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308266 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008267}
8268
8269OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8270{
Arun Menon906de572013-06-18 17:01:40 -07008271 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8272 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8273 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008274
Arun Menon906de572013-06-18 17:01:40 -07008275 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008276 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07008277 int nBufHdrSize = 0;
8278 int nPlatformEntrySize = 0;
8279 int nPlatformListSize = 0;
8280 int nPMEMInfoSize = 0;
8281 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8282 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8283 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008284
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008285 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008286 drv_ctx.op_buf.actualcount);
8287 nBufHdrSize = drv_ctx.op_buf.actualcount *
8288 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008289
Arun Menon906de572013-06-18 17:01:40 -07008290 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8291 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8292 nPlatformListSize = drv_ctx.op_buf.actualcount *
8293 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8294 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8295 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008296
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008297 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07008298 sizeof(OMX_BUFFERHEADERTYPE),
8299 nPMEMInfoSize,
8300 nPlatformListSize);
Deva Ramasubramanianeb819322014-07-17 14:23:35 -07008301 DEBUG_PRINT_LOW("PE %d bmSize %"PRId64, nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07008302 m_out_bm_count);
8303 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8304 // Alloc mem for platform specific info
8305 char *pPtr=NULL;
8306 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8307 nPMEMInfoSize,1);
8308 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8309 calloc (sizeof(struct vdec_bufferpayload),
8310 drv_ctx.op_buf.actualcount);
8311 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8312 calloc (sizeof (struct vdec_output_frameinfo),
8313 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008314 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
8315 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
8316 return OMX_ErrorInsufficientResources;
8317 }
8318
Shalaj Jain273b3e02012-06-22 19:08:03 -07008319#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008320 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8321 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008322 if (!drv_ctx.op_buf_ion_info) {
8323 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
8324 return OMX_ErrorInsufficientResources;
8325 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008326#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07008327 if (dynamic_buf_mode) {
8328 out_dynamic_list = (struct dynamic_buf_list *) \
8329 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
8330 }
Arun Menon906de572013-06-18 17:01:40 -07008331 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8332 && drv_ctx.ptr_respbuffer) {
8333 bufHdr = m_out_mem_ptr;
8334 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8335 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8336 (((char *) m_platform_list) + nPlatformListSize);
8337 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8338 (((char *) m_platform_entry) + nPlatformEntrySize);
8339 pPlatformList = m_platform_list;
8340 pPlatformEntry = m_platform_entry;
8341 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008342
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008343 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008344
Arun Menon906de572013-06-18 17:01:40 -07008345 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008346 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07008347 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008348 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07008349 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
8350 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8351 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8352 // Set the values when we determine the right HxW param
8353 bufHdr->nAllocLen = 0;
8354 bufHdr->nFilledLen = 0;
8355 bufHdr->pAppPrivate = NULL;
8356 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8357 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8358 pPlatformEntry->entry = pPMEMInfo;
8359 // Initialize the Platform List
8360 pPlatformList->nEntries = 1;
8361 pPlatformList->entryList = pPlatformEntry;
8362 // Keep pBuffer NULL till vdec is opened
8363 bufHdr->pBuffer = NULL;
8364 pPMEMInfo->offset = 0;
8365 pPMEMInfo->pmem_fd = 0;
8366 bufHdr->pPlatformPrivate = pPlatformList;
8367 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008368#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008369 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008370#endif
Arun Menon906de572013-06-18 17:01:40 -07008371 /*Create a mapping between buffers*/
8372 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8373 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8374 &drv_ctx.ptr_outputbuffer[i];
8375 // Move the buffer and buffer header pointers
8376 bufHdr++;
8377 pPMEMInfo++;
8378 pPlatformEntry++;
8379 pPlatformList++;
8380 }
8381 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008382 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008383 m_out_mem_ptr, pPtr);
8384 if (m_out_mem_ptr) {
8385 free(m_out_mem_ptr);
8386 m_out_mem_ptr = NULL;
8387 }
8388 if (pPtr) {
8389 free(pPtr);
8390 pPtr = NULL;
8391 }
8392 if (drv_ctx.ptr_outputbuffer) {
8393 free(drv_ctx.ptr_outputbuffer);
8394 drv_ctx.ptr_outputbuffer = NULL;
8395 }
8396 if (drv_ctx.ptr_respbuffer) {
8397 free(drv_ctx.ptr_respbuffer);
8398 drv_ctx.ptr_respbuffer = NULL;
8399 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008400#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008401 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008402 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008403 free(drv_ctx.op_buf_ion_info);
8404 drv_ctx.op_buf_ion_info = NULL;
8405 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008406#endif
Arun Menon906de572013-06-18 17:01:40 -07008407 eRet = OMX_ErrorInsufficientResources;
8408 }
8409 } else {
8410 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008411 }
Arun Menon906de572013-06-18 17:01:40 -07008412 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008413}
8414
8415void omx_vdec::complete_pending_buffer_done_cbs()
8416{
Arun Menon906de572013-06-18 17:01:40 -07008417 unsigned p1;
8418 unsigned p2;
8419 unsigned ident;
8420 omx_cmd_queue tmp_q, pending_bd_q;
8421 pthread_mutex_lock(&m_lock);
8422 // pop all pending GENERATE FDB from ftb queue
8423 while (m_ftb_q.m_size) {
8424 m_ftb_q.pop_entry(&p1,&p2,&ident);
8425 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8426 pending_bd_q.insert_entry(p1,p2,ident);
8427 } else {
8428 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008429 }
Arun Menon906de572013-06-18 17:01:40 -07008430 }
8431 //return all non GENERATE FDB to ftb queue
8432 while (tmp_q.m_size) {
8433 tmp_q.pop_entry(&p1,&p2,&ident);
8434 m_ftb_q.insert_entry(p1,p2,ident);
8435 }
8436 // pop all pending GENERATE EDB from etb queue
8437 while (m_etb_q.m_size) {
8438 m_etb_q.pop_entry(&p1,&p2,&ident);
8439 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8440 pending_bd_q.insert_entry(p1,p2,ident);
8441 } else {
8442 tmp_q.insert_entry(p1,p2,ident);
8443 }
8444 }
8445 //return all non GENERATE FDB to etb queue
8446 while (tmp_q.m_size) {
8447 tmp_q.pop_entry(&p1,&p2,&ident);
8448 m_etb_q.insert_entry(p1,p2,ident);
8449 }
8450 pthread_mutex_unlock(&m_lock);
8451 // process all pending buffer dones
8452 while (pending_bd_q.m_size) {
8453 pending_bd_q.pop_entry(&p1,&p2,&ident);
8454 switch (ident) {
8455 case OMX_COMPONENT_GENERATE_EBD:
8456 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008457 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008458 omx_report_error ();
8459 }
8460 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008461
Arun Menon906de572013-06-18 17:01:40 -07008462 case OMX_COMPONENT_GENERATE_FBD:
8463 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008464 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008465 omx_report_error ();
8466 }
8467 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008468 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008469 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008470}
8471
8472void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8473{
Arun Menon906de572013-06-18 17:01:40 -07008474 OMX_U32 new_frame_interval = 0;
8475 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8476 && llabs(act_timestamp - prev_ts) > 2000) {
8477 new_frame_interval = client_set_fps ? frm_int :
8478 llabs(act_timestamp - prev_ts);
Arun Menond9e49f82014-04-23 18:50:26 -07008479 if (new_frame_interval != frm_int || frm_int == 0) {
Arun Menon906de572013-06-18 17:01:40 -07008480 frm_int = new_frame_interval;
8481 if (frm_int) {
8482 drv_ctx.frame_rate.fps_numerator = 1e6;
8483 drv_ctx.frame_rate.fps_denominator = frm_int;
8484 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8485 frm_int, drv_ctx.frame_rate.fps_numerator /
8486 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008487
Arun Menon906de572013-06-18 17:01:40 -07008488 /* We need to report the difference between this FBD and the previous FBD
8489 * back to the driver for clock scaling purposes. */
8490 struct v4l2_outputparm oparm;
8491 /*XXX: we're providing timing info as seconds per frame rather than frames
8492 * per second.*/
8493 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8494 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008495
Arun Menon906de572013-06-18 17:01:40 -07008496 struct v4l2_streamparm sparm;
8497 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8498 sparm.parm.output = oparm;
8499 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8500 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8501 performance might be affected");
8502 }
8503
8504 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008505 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008506 }
Arun Menon906de572013-06-18 17:01:40 -07008507 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008508}
8509
8510void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8511{
Arun Menon906de572013-06-18 17:01:40 -07008512 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8513 prev_ts = act_timestamp;
8514 rst_prev_ts = false;
8515 } else if (VALID_TS(prev_ts)) {
8516 bool codec_cond = (drv_ctx.timestamp_adjust)?
8517 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8518 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8519 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8520 if (frm_int > 0 && codec_cond) {
8521 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8522 act_timestamp = prev_ts + frm_int;
8523 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8524 prev_ts = act_timestamp;
Leena Winterrowdd139fdc2014-08-05 18:04:25 -07008525 } else {
8526 if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
8527 // ensure that timestamps can never step backwards when in display order
8528 act_timestamp = prev_ts;
8529 }
Arun Menon906de572013-06-18 17:01:40 -07008530 set_frame_rate(act_timestamp);
Leena Winterrowdd139fdc2014-08-05 18:04:25 -07008531 }
Arun Menon906de572013-06-18 17:01:40 -07008532 } else if (frm_int > 0) // In this case the frame rate was set along
8533 { // with the port definition, start ts with 0
8534 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8535 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008536 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008537}
8538
8539void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8540{
Arun Menon906de572013-06-18 17:01:40 -07008541 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8542 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308543 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008544 OMX_U32 frame_rate = 0;
8545 int consumed_len = 0;
8546 OMX_U32 num_MB_in_frame;
8547 OMX_U32 recovery_sei_flags = 1;
8548 int enable = 0;
Arun Menon7b6fd642014-02-13 16:48:36 -08008549
Arun Menon906de572013-06-18 17:01:40 -07008550 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008551 if (buf_index >= drv_ctx.extradata_info.count) {
8552 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8553 buf_index, drv_ctx.extradata_info.count);
8554 return;
8555 }
Arun Menon906de572013-06-18 17:01:40 -07008556 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8557 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8558 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308559
Arun Menon906de572013-06-18 17:01:40 -07008560 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308561 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008562 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008563 }
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308564
8565 if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
8566 DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
8567 p_extra = NULL;
8568 return;
8569 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308570 if (!secure_mode)
8571 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008572 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308573 else
8574 p_extra = m_other_extradata;
8575
Arun Menon906de572013-06-18 17:01:40 -07008576 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308577 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
8578 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
Arun Menon906de572013-06-18 17:01:40 -07008579 p_extra = NULL;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308580 return;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008581 }
Arun Menon906de572013-06-18 17:01:40 -07008582 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008583 if (data && p_extra) {
Arun Menon906de572013-06-18 17:01:40 -07008584 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8585 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308586 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008587 DEBUG_PRINT_LOW("Invalid extra data size");
8588 break;
8589 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308590 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008591 switch ((unsigned long)data->eType) {
8592 case EXTRADATA_INTERLACE_VIDEO:
8593 struct msm_vidc_interlace_payload *payload;
8594 payload = (struct msm_vidc_interlace_payload *)data->data;
Arun Menon7b6fd642014-02-13 16:48:36 -08008595 if (payload) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008596 enable = 1;
Arun Menon7b6fd642014-02-13 16:48:36 -08008597 switch (payload->format) {
8598 case INTERLACE_FRAME_PROGRESSIVE:
8599 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8600 enable = 0;
8601 break;
8602 case INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
8603 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8604 break;
8605 case INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
8606 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
8607 break;
8608 default:
8609 DEBUG_PRINT_LOW("default case - set interlace to topfield");
8610 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8611 }
Arun Menon906de572013-06-18 17:01:40 -07008612 }
8613 if (m_enable_android_native_buffers)
8614 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8615 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308616 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon7b6fd642014-02-13 16:48:36 -08008617 append_interlace_extradata(p_extra, payload->format,
8618 p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
Arun Menon906de572013-06-18 17:01:40 -07008619 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8620 }
8621 break;
8622 case EXTRADATA_FRAME_RATE:
8623 struct msm_vidc_framerate_payload *frame_rate_payload;
8624 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8625 frame_rate = frame_rate_payload->frame_rate;
8626 break;
8627 case EXTRADATA_TIMESTAMP:
8628 struct msm_vidc_ts_payload *time_stamp_payload;
8629 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308630 time_stamp = time_stamp_payload->timestamp_lo;
8631 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8632 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008633 break;
8634 case EXTRADATA_NUM_CONCEALED_MB:
8635 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8636 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8637 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8638 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8639 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8640 break;
8641 case EXTRADATA_INDEX:
8642 int *etype;
8643 etype = (int *)(data->data);
8644 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8645 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8646 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8647 if (aspect_ratio_payload) {
8648 ((struct vdec_output_frameinfo *)
8649 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8650 ((struct vdec_output_frameinfo *)
8651 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8652 }
8653 }
8654 break;
8655 case EXTRADATA_RECOVERY_POINT_SEI:
8656 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8657 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8658 recovery_sei_flags = recovery_sei_payload->flags;
8659 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8660 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008661 DEBUG_PRINT_HIGH("");
8662 DEBUG_PRINT_HIGH("***************************************************");
8663 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8664 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008665 }
8666 break;
8667 case EXTRADATA_PANSCAN_WINDOW:
8668 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8669 break;
8670 case EXTRADATA_MPEG2_SEQDISP:
8671 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8672 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8673 if (seqdisp_payload) {
8674 m_disp_hor_size = seqdisp_payload->disp_width;
8675 m_disp_vert_size = seqdisp_payload->disp_height;
8676 }
8677 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308678 case EXTRADATA_S3D_FRAME_PACKING:
8679 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8680 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308681 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308682 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8683 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8684 }
8685 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008686 case EXTRADATA_FRAME_QP:
8687 struct msm_vidc_frame_qp_payload *qp_payload;
8688 qp_payload = (struct msm_vidc_frame_qp_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308689 if (client_extradata & OMX_QP_EXTRADATA) {
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008690 append_qp_extradata(p_extra, qp_payload);
8691 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8692 }
8693 break;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008694 case EXTRADATA_FRAME_BITS_INFO:
8695 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
8696 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308697 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008698 append_bitsinfo_extradata(p_extra, bits_info_payload);
8699 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8700 }
8701 break;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008702 case EXTRADATA_STREAM_USERDATA:
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308703 if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008704 append_user_extradata(p_extra, data);
8705 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8706 }
8707 break;
Arun Menon906de572013-06-18 17:01:40 -07008708 default:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008709 DEBUG_PRINT_LOW("Unrecognized extradata");
Arun Menon906de572013-06-18 17:01:40 -07008710 goto unrecognized_extradata;
8711 }
8712 consumed_len += data->nSize;
8713 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8714 }
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308715 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008716 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8717 append_frame_info_extradata(p_extra,
8718 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308719 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008720 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008721 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008722 }
8723 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008724unrecognized_extradata:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008725 if (client_extradata && p_extra) {
8726 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Arun Menon906de572013-06-18 17:01:40 -07008727 append_terminator_extradata(p_extra);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008728 }
8729
Arun Menonfd723932014-05-30 17:56:31 -07008730 if (secure_mode && p_extradata && m_other_extradata) {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308731 struct vdec_output_frameinfo *ptr_extradatabuff = NULL;
8732 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
8733 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
8734 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
8735 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
8736 }
Arun Menon906de572013-06-18 17:01:40 -07008737 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008738}
8739
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008740OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008741 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008742{
Arun Menon906de572013-06-18 17:01:40 -07008743 OMX_ERRORTYPE ret = OMX_ErrorNone;
8744 struct v4l2_control control;
8745 if (m_state != OMX_StateLoaded) {
8746 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8747 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008748 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008749 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008750 client_extradata, requested_extradata, enable, is_internal);
8751
8752 if (!is_internal) {
8753 if (enable)
8754 client_extradata |= requested_extradata;
8755 else
8756 client_extradata = client_extradata & ~requested_extradata;
8757 }
8758
8759 if (enable) {
8760 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8761 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8762 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8763 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8764 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008765 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008766 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308767 }
8768 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008769 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8770 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8771 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008772 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008773 }
8774 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8775 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8776 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008777 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008778 }
8779 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8780 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8781 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008782 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008783 }
8784 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8785 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8786 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008787 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008788 }
8789 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8790 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8791 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008792 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008793 }
8794 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8795 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8796 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8797 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008798 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008799 }
8800 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308801 }
8802 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008803 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8804 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8805 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008806 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008807 }
8808 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308809 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8810 if (output_capability == V4L2_PIX_FMT_H264) {
8811 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8812 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8813 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8814 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8815 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8816 }
8817 } else {
8818 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8819 }
8820 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008821 if (requested_extradata & OMX_QP_EXTRADATA) {
8822 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8823 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
8824 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8825 DEBUG_PRINT_HIGH("Failed to set QP extradata");
8826 }
8827 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008828 if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
8829 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8830 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
8831 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8832 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
8833 }
8834 }
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008835 if (requested_extradata & OMX_EXTNUSER_EXTRADATA) {
8836 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8837 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
8838 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8839 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
8840 }
8841 }
Arun Menon906de572013-06-18 17:01:40 -07008842 }
8843 ret = get_buffer_req(&drv_ctx.op_buf);
8844 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008845}
8846
8847OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8848{
Arun Menon906de572013-06-18 17:01:40 -07008849 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8850 OMX_U8 *data_ptr = extra->data, data = 0;
8851 while (byte_count < extra->nDataSize) {
8852 data = *data_ptr;
8853 while (data) {
8854 num_MB += (data&0x01);
8855 data >>= 1;
8856 }
8857 data_ptr++;
8858 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008859 }
Arun Menon906de572013-06-18 17:01:40 -07008860 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8861 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8862 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008863}
8864
8865void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8866{
Arun Menon906de572013-06-18 17:01:40 -07008867 if (!m_debug_extradata)
8868 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008869
8870 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308871 "============== Extra Data ==============\n"
8872 " Size: %lu\n"
8873 " Version: %lu\n"
8874 " PortIndex: %lu\n"
8875 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008876 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008877 extra->nSize, extra->nVersion.nVersion,
8878 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008879
Arun Menon906de572013-06-18 17:01:40 -07008880 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8881 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8882 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308883 "------ Interlace Format ------\n"
8884 " Size: %lu\n"
8885 " Version: %lu\n"
8886 " PortIndex: %lu\n"
8887 " Is Interlace Format: %d\n"
8888 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008889 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008890 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8891 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8892 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8893 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8894
8895 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308896 "-------- Frame Format --------\n"
8897 " Picture Type: %d\n"
8898 " Interlace Type: %d\n"
8899 " Pan Scan Total Frame Num: %lu\n"
8900 " Concealed Macro Blocks: %lu\n"
8901 " frame rate: %lu\n"
8902 " Time Stamp: %llu\n"
8903 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008904 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008905 fminfo->ePicType,
8906 fminfo->interlaceType,
8907 fminfo->panScan.numWindows,
8908 fminfo->nConcealedMacroblocks,
8909 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308910 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008911 fminfo->aspectRatio.aspectRatioX,
8912 fminfo->aspectRatio.aspectRatioY);
8913
8914 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8915 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008916 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308917 " Pan Scan Frame Num: %lu\n"
8918 " Rectangle x: %ld\n"
8919 " Rectangle y: %ld\n"
8920 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008921 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008922 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8923 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8924 }
8925
8926 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308927 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8928 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8929 DEBUG_PRINT_HIGH(
8930 "------------------ Framepack Format ----------\n"
8931 " id: %lu \n"
8932 " cancel_flag: %lu \n"
8933 " type: %lu \n"
8934 " quincunx_sampling_flagFormat: %lu \n"
8935 " content_interpretation_type: %lu \n"
8936 " content_interpretation_type: %lu \n"
8937 " spatial_flipping_flag: %lu \n"
8938 " frame0_flipped_flag: %lu \n"
8939 " field_views_flag: %lu \n"
8940 " current_frame_is_frame0_flag: %lu \n"
8941 " frame0_self_contained_flag: %lu \n"
8942 " frame1_self_contained_flag: %lu \n"
8943 " frame0_grid_position_x: %lu \n"
8944 " frame0_grid_position_y: %lu \n"
8945 " frame1_grid_position_x: %lu \n"
8946 " frame1_grid_position_y: %lu \n"
8947 " reserved_byte: %lu \n"
8948 " repetition_period: %lu \n"
8949 " extension_flag: %lu \n"
8950 "================== End of Framepack ===========",
8951 framepack->id,
8952 framepack->cancel_flag,
8953 framepack->type,
8954 framepack->quincunx_sampling_flag,
8955 framepack->content_interpretation_type,
8956 framepack->spatial_flipping_flag,
8957 framepack->frame0_flipped_flag,
8958 framepack->field_views_flag,
8959 framepack->current_frame_is_frame0_flag,
8960 framepack->frame0_self_contained_flag,
8961 framepack->frame1_self_contained_flag,
8962 framepack->frame0_grid_position_x,
8963 framepack->frame0_grid_position_y,
8964 framepack->frame1_grid_position_x,
8965 framepack->frame1_grid_position_y,
8966 framepack->reserved_byte,
8967 framepack->repetition_period,
8968 framepack->extension_flag);
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008969 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
8970 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8971 DEBUG_PRINT_HIGH(
8972 "---- QP (Frame quantization parameter) ----\n"
8973 " Frame QP: %lu \n"
8974 "================ End of QP ================\n",
8975 qp->nQP);
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008976 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
8977 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)extra->data;
8978 DEBUG_PRINT_HIGH(
8979 "--------- Input bits information --------\n"
8980 " Header bits: %lu \n"
8981 " Frame bits: %lu \n"
8982 "===== End of Input bits information =====\n",
8983 bits->header_bits, bits->frame_bits);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008984 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
8985 OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)extra->data;
8986 OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
8987 OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
8988 OMX_U32 i = 0;
8989 DEBUG_PRINT_HIGH(
8990 "-------------- Userdata -------------\n"
8991 " Stream userdata type: %d\n"
8992 " userdata size: %d\n"
8993 " STREAM_USERDATA:",
8994 userdata->type, userdata_size);
8995 for (i = 0; i < userdata_size; i+=4) {
8996 DEBUG_PRINT_HIGH(" %x %x %x %x",
8997 data_ptr[i], data_ptr[i+1],
8998 data_ptr[i+2], data_ptr[i+3]);
8999 }
9000 DEBUG_PRINT_HIGH(
9001 "=========== End of Userdata ===========");
Arun Menon906de572013-06-18 17:01:40 -07009002 } else if (extra->eType == OMX_ExtraDataNone) {
9003 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
9004 } else {
9005 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07009006 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009007}
9008
9009void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon7b6fd642014-02-13 16:48:36 -08009010 OMX_U32 interlaced_format_type, bool is_mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009011{
Arun Menon906de572013-06-18 17:01:40 -07009012 OMX_STREAMINTERLACEFORMAT *interlace_format;
Arun Menon7b6fd642014-02-13 16:48:36 -08009013
Arun Menon906de572013-06-18 17:01:40 -07009014 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
9015 return;
9016 }
9017 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
9018 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9019 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9020 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
9021 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9022 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
9023 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9024 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
9025 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
Arun Menon7b6fd642014-02-13 16:48:36 -08009026
9027 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
Arun Menon906de572013-06-18 17:01:40 -07009028 interlace_format->bInterlaceFormat = OMX_FALSE;
9029 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
9030 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08009031 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009032 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08009033 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009034 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08009035 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009036 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08009037 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009038 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07009039 } else {
9040 interlace_format->bInterlaceFormat = OMX_TRUE;
9041 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
9042 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
9043 }
9044 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009045}
9046
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009047void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07009048 struct vdec_aspectratioinfo *aspect_ratio_info,
9049 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009050{
Arun Menon906de572013-06-18 17:01:40 -07009051 m_extradata = frame_info;
9052 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
9053 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309054 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07009055 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009056}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009057
9058void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07009059 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309060 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009061 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009062{
Arun Menon906de572013-06-18 17:01:40 -07009063 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
9064 struct msm_vidc_panscan_window *panscan_window;
9065 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009066 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009067 }
Arun Menon906de572013-06-18 17:01:40 -07009068 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
9069 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9070 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9071 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
9072 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
9073 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
9074 switch (picture_type) {
9075 case PICTURE_TYPE_I:
9076 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
9077 break;
9078 case PICTURE_TYPE_P:
9079 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
9080 break;
9081 case PICTURE_TYPE_B:
9082 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
9083 break;
9084 default:
9085 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
9086 }
9087 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
9088 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
9089 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
9090 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
9091 else
9092 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
9093 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
9094 frame_info->nConcealedMacroblocks = num_conceal_mb;
9095 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309096 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07009097 frame_info->panScan.numWindows = 0;
9098 if (output_capability == V4L2_PIX_FMT_MPEG2) {
9099 if (m_disp_hor_size && m_disp_vert_size) {
9100 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
9101 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
Pushkaraj Patil5e6ebd92014-03-10 10:29:14 +05309102 } else {
9103 frame_info->displayAspectRatio.displayHorizontalSize = 0;
9104 frame_info->displayAspectRatio.displayVerticalSize = 0;
Arun Menon906de572013-06-18 17:01:40 -07009105 }
9106 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009107
Arun Menon906de572013-06-18 17:01:40 -07009108 if (panscan_payload) {
9109 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
9110 panscan_window = &panscan_payload->wnd[0];
9111 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
9112 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
9113 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
9114 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
9115 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
9116 panscan_window++;
9117 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009118 }
Arun Menon906de572013-06-18 17:01:40 -07009119 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
9120 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009121}
9122
9123void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9124{
Arun Menon906de572013-06-18 17:01:40 -07009125 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
9126 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
9127 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9128 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9129 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
9130 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
9131 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
9132 *portDefn = m_port_def;
9133 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009134 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07009135 portDefn->format.video.nFrameWidth,
9136 portDefn->format.video.nStride,
9137 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009138}
9139
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05309140void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9141 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
9142{
9143 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
9144 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
9145 DEBUG_PRINT_ERROR("frame packing size mismatch");
9146 return;
9147 }
9148 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
9149 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9150 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9151 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
9152 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9153 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
9154 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9155 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
9156 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9157 memcpy(&framepack->id, s3d_frame_packing_payload,
9158 sizeof(struct msm_vidc_s3d_frame_packing_payload));
9159 memcpy(&m_frame_pack_arrangement, framepack,
9160 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
9161 print_debug_extradata(extra);
9162}
9163
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08009164void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9165 struct msm_vidc_frame_qp_payload *qp_payload)
9166{
9167 OMX_QCOM_EXTRADATA_QP * qp = NULL;
9168 if (!qp_payload) {
9169 DEBUG_PRINT_ERROR("QP payload is NULL");
9170 return;
9171 }
9172 extra->nSize = OMX_QP_EXTRADATA_SIZE;
9173 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9174 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9175 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
9176 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
9177 qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
9178 qp->nQP = qp_payload->frame_qp;
9179 print_debug_extradata(extra);
9180}
9181
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08009182void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9183 struct msm_vidc_frame_bits_info_payload *bits_payload)
9184{
9185 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
9186 if (!bits_payload) {
9187 DEBUG_PRINT_ERROR("bits info payload is NULL");
9188 return;
9189 }
9190 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
9191 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9192 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9193 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
9194 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
9195 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)extra->data;
9196 bits->frame_bits = bits_payload->frame_bits;
9197 bits->header_bits = bits_payload->header_bits;
9198 print_debug_extradata(extra);
9199}
9200
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009201void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9202 OMX_OTHER_EXTRADATATYPE *p_user)
9203{
9204 int userdata_size = 0;
9205 struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
9206 userdata_payload =
9207 (struct msm_vidc_stream_userdata_payload *)p_user->data;
9208 userdata_size = p_user->nDataSize;
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07009209 extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + p_user->nSize;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009210 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9211 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9212 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
9213 extra->nDataSize = userdata_size;
9214 if (extra->data && p_user->data && extra->nDataSize)
9215 memcpy(extra->data, p_user->data, extra->nDataSize);
9216 print_debug_extradata(extra);
9217}
9218
Shalaj Jain273b3e02012-06-22 19:08:03 -07009219void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9220{
Arun Menon906de572013-06-18 17:01:40 -07009221 if (!client_extradata) {
9222 return;
9223 }
9224 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
9225 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9226 extra->eType = OMX_ExtraDataNone;
9227 extra->nDataSize = 0;
9228 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009229
Arun Menon906de572013-06-18 17:01:40 -07009230 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009231}
9232
9233OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
9234{
Arun Menon906de572013-06-18 17:01:40 -07009235 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9236 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009237 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07009238 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009239 }
Arun Menon906de572013-06-18 17:01:40 -07009240 if (m_desc_buffer_ptr == NULL) {
9241 m_desc_buffer_ptr = (desc_buffer_hdr*) \
9242 calloc( (sizeof(desc_buffer_hdr)),
9243 drv_ctx.ip_buf.actualcount);
9244 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009245 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009246 return OMX_ErrorInsufficientResources;
9247 }
9248 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009249
Arun Menon906de572013-06-18 17:01:40 -07009250 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
9251 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009252 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009253 return OMX_ErrorInsufficientResources;
9254 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009255
Arun Menon906de572013-06-18 17:01:40 -07009256 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009257}
9258
9259void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
9260{
Arun Menon906de572013-06-18 17:01:40 -07009261 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
9262 if (m_demux_entries < 8192) {
9263 m_demux_offsets[m_demux_entries++] = address_offset;
9264 }
9265 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009266}
9267
9268void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
9269{
Arun Menon906de572013-06-18 17:01:40 -07009270 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
9271 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
9272 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009273
Arun Menon906de572013-06-18 17:01:40 -07009274 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009275
Arun Menon906de572013-06-18 17:01:40 -07009276 while (index < bytes_to_parse) {
9277 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9278 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
9279 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9280 (buf[index+2] == 0x01)) ) {
9281 //Found start code, insert address offset
9282 insert_demux_addr_offset(index);
9283 if (buf[index+2] == 0x01) // 3 byte start code
9284 index += 3;
9285 else //4 byte start code
9286 index += 4;
9287 } else
9288 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009289 }
Arun Menon906de572013-06-18 17:01:40 -07009290 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
9291 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009292}
9293
9294OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
9295{
Arun Menon906de572013-06-18 17:01:40 -07009296 //fix this, handle 3 byte start code, vc1 terminator entry
9297 OMX_U8 *p_demux_data = NULL;
9298 OMX_U32 desc_data = 0;
9299 OMX_U32 start_addr = 0;
9300 OMX_U32 nal_size = 0;
9301 OMX_U32 suffix_byte = 0;
9302 OMX_U32 demux_index = 0;
9303 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009304
Arun Menon906de572013-06-18 17:01:40 -07009305 if (m_desc_buffer_ptr == NULL) {
9306 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
9307 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009308 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009309
Arun Menon906de572013-06-18 17:01:40 -07009310 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
9311 if (buffer_index > drv_ctx.ip_buf.actualcount) {
9312 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
9313 return OMX_ErrorBadParameter;
9314 }
9315
9316 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9317
9318 if ( ((OMX_U8*)p_demux_data == NULL) ||
9319 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
9320 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9321 return OMX_ErrorBadParameter;
9322 } else {
9323 for (; demux_index < m_demux_entries; demux_index++) {
9324 desc_data = 0;
9325 start_addr = m_demux_offsets[demux_index];
9326 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
9327 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9328 } else {
9329 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9330 }
9331 if (demux_index < (m_demux_entries - 1)) {
9332 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9333 } else {
9334 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9335 }
9336 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9337 (void *)start_addr,
9338 suffix_byte,
9339 nal_size,
9340 demux_index);
9341 desc_data = (start_addr >> 3) << 1;
9342 desc_data |= (start_addr & 7) << 21;
9343 desc_data |= suffix_byte << 24;
9344
9345 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9346 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9347 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9348 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9349
9350 p_demux_data += 16;
9351 }
9352 if (codec_type_parse == CODEC_TYPE_VC1) {
9353 DEBUG_PRINT_LOW("VC1 terminator entry");
9354 desc_data = 0;
9355 desc_data = 0x82 << 24;
9356 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9357 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9358 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9359 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9360 p_demux_data += 16;
9361 m_demux_entries++;
9362 }
9363 //Add zero word to indicate end of descriptors
9364 memset(p_demux_data, 0, sizeof(OMX_U32));
9365
9366 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
9367 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
9368 }
9369 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9370 m_demux_entries = 0;
9371 DEBUG_PRINT_LOW("Demux table complete!");
9372 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009373}
9374
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009375OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009376{
Arun Menon906de572013-06-18 17:01:40 -07009377 OMX_ERRORTYPE err = OMX_ErrorNone;
9378 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9379 if (iDivXDrmDecrypt) {
9380 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9381 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009382 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009383 delete iDivXDrmDecrypt;
9384 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07009385 }
9386 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009387 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07009388 err = OMX_ErrorUndefined;
9389 }
9390 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009391}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009392
Vinay Kaliada4f4422013-01-09 10:45:03 -08009393omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9394{
Arun Menon906de572013-06-18 17:01:40 -07009395 enabled = false;
9396 omx = NULL;
9397 init_members();
9398 ColorFormat = OMX_COLOR_FormatMax;
Praveen Chavandb7776f2014-02-06 18:17:25 -08009399 dest_format = YCbCr420P;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009400}
9401
9402void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9403{
Arun Menon906de572013-06-18 17:01:40 -07009404 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009405}
9406
Arun Menon906de572013-06-18 17:01:40 -07009407void omx_vdec::allocate_color_convert_buf::init_members()
9408{
9409 allocated_count = 0;
9410 buffer_size_req = 0;
9411 buffer_alignment_req = 0;
9412 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9413 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9414 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9415 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009416#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009417 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009418#endif
Arun Menon906de572013-06-18 17:01:40 -07009419 for (int i = 0; i < MAX_COUNT; i++)
9420 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009421}
9422
Arun Menon906de572013-06-18 17:01:40 -07009423omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9424{
9425 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08009426}
9427
9428bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9429{
Arun Menon906de572013-06-18 17:01:40 -07009430 bool status = true;
9431 unsigned int src_size = 0, destination_size = 0;
9432 OMX_COLOR_FORMATTYPE drv_color_format;
9433 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009434 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009435 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009436 }
Arun Menon906de572013-06-18 17:01:40 -07009437 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009438 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07009439 return status;
9440 }
9441 pthread_mutex_lock(&omx->c_lock);
9442 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9443 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009444 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07009445 status = false;
9446 goto fail_update_buf_req;
9447 }
9448 c2d.close();
9449 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9450 omx->drv_ctx.video_resolution.frame_width,
Praveen Chavandb7776f2014-02-06 18:17:25 -08009451 NV12_128m,dest_format);
Arun Menon906de572013-06-18 17:01:40 -07009452 if (status) {
9453 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9454 if (status)
9455 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9456 }
9457 if (status) {
9458 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9459 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009460 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07009461 "driver size %d destination size %d",
9462 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9463 status = false;
9464 c2d.close();
9465 buffer_size_req = 0;
9466 } else {
9467 buffer_size_req = destination_size;
9468 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9469 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9470 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9471 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9472 }
9473 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009474fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07009475 pthread_mutex_unlock(&omx->c_lock);
9476 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009477}
9478
9479bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07009480 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009481{
Arun Menon906de572013-06-18 17:01:40 -07009482 bool status = true;
9483 OMX_COLOR_FORMATTYPE drv_color_format;
9484 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009485 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009486 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009487 }
Arun Menon906de572013-06-18 17:01:40 -07009488 pthread_mutex_lock(&omx->c_lock);
9489 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9490 drv_color_format = (OMX_COLOR_FORMATTYPE)
9491 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9492 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009493 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07009494 status = false;
9495 }
9496 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009497 DEBUG_PRINT_LOW("Enabling C2D");
Praveen Chavandb7776f2014-02-06 18:17:25 -08009498 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
9499 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009500 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009501 status = false;
9502 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009503 ColorFormat = dest_color_format;
9504 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
9505 YCbCr420P : YCbCr420SP;
Arun Menon906de572013-06-18 17:01:40 -07009506 if (enabled)
9507 c2d.destroy();
9508 enabled = false;
9509 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009510 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009511 status = false;
9512 } else
9513 enabled = true;
9514 }
9515 } else {
9516 if (enabled)
9517 c2d.destroy();
9518 enabled = false;
9519 }
9520 pthread_mutex_unlock(&omx->c_lock);
9521 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009522}
9523
9524OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9525{
Arun Menon906de572013-06-18 17:01:40 -07009526 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009527 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009528 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009529 }
Arun Menon906de572013-06-18 17:01:40 -07009530 if (!enabled)
9531 return omx->m_out_mem_ptr;
9532 return m_out_mem_ptr_client;
9533}
9534
9535 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9536(OMX_BUFFERHEADERTYPE *bufadd)
9537{
9538 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009539 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009540 return NULL;
9541 }
9542 if (!enabled)
9543 return bufadd;
9544
9545 unsigned index = 0;
9546 index = bufadd - omx->m_out_mem_ptr;
9547 if (index < omx->drv_ctx.op_buf.actualcount) {
9548 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9549 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9550 bool status;
9551 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9552 pthread_mutex_lock(&omx->c_lock);
9553 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9554 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9555 pmem_baseaddress[index], pmem_baseaddress[index]);
Arun Menon906de572013-06-18 17:01:40 -07009556 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009557 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009558 m_out_mem_ptr_client[index].nFilledLen = 0;
Leena Winterrowd270a7042014-09-30 13:05:55 -07009559 pthread_mutex_unlock(&omx->c_lock);
Arun Menon906de572013-06-18 17:01:40 -07009560 return &m_out_mem_ptr_client[index];
Praveen Chavan6d6b7252014-09-15 17:05:54 -07009561 } else {
9562 unsigned int filledLen = 0;
9563 c2d.get_output_filled_length(filledLen);
9564 m_out_mem_ptr_client[index].nFilledLen = filledLen;
Arun Menon906de572013-06-18 17:01:40 -07009565 }
Leena Winterrowd270a7042014-09-30 13:05:55 -07009566 pthread_mutex_unlock(&omx->c_lock);
Arun Menon906de572013-06-18 17:01:40 -07009567 } else
9568 m_out_mem_ptr_client[index].nFilledLen = 0;
9569 return &m_out_mem_ptr_client[index];
9570 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009571 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009572 return NULL;
9573}
9574
9575 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9576(OMX_BUFFERHEADERTYPE *bufadd)
9577{
9578 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009579 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009580 return NULL;
9581 }
9582 if (!enabled)
9583 return bufadd;
9584 unsigned index = 0;
9585 index = bufadd - m_out_mem_ptr_client;
9586 if (index < omx->drv_ctx.op_buf.actualcount) {
9587 return &omx->m_out_mem_ptr[index];
9588 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009589 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009590 return NULL;
9591}
9592 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9593(unsigned int &buffer_size)
9594{
9595 bool status = true;
9596 pthread_mutex_lock(&omx->c_lock);
9597 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009598 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009599 else {
9600 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009601 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009602 status = false;
9603 goto fail_get_buffer_size;
9604 }
9605 }
9606 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9607 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9608 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9609 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009610fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009611 pthread_mutex_unlock(&omx->c_lock);
9612 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009613}
9614OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009615 OMX_BUFFERHEADERTYPE *bufhdr)
9616{
9617 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009618
Arun Menon906de572013-06-18 17:01:40 -07009619 if (!enabled)
9620 return omx->free_output_buffer(bufhdr);
9621 if (enabled && omx->is_component_secure())
9622 return OMX_ErrorNone;
9623 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009624 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009625 return OMX_ErrorBadParameter;
9626 }
9627 index = bufhdr - m_out_mem_ptr_client;
9628 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009629 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009630 return OMX_ErrorBadParameter;
9631 }
9632 if (pmem_fd[index] > 0) {
9633 munmap(pmem_baseaddress[index], buffer_size_req);
9634 close(pmem_fd[index]);
9635 }
9636 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009637#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009638 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009639#endif
Arun Menon906de572013-06-18 17:01:40 -07009640 m_heap_ptr[index].video_heap_ptr = NULL;
9641 if (allocated_count > 0)
9642 allocated_count--;
9643 else
9644 allocated_count = 0;
9645 if (!allocated_count) {
9646 pthread_mutex_lock(&omx->c_lock);
9647 c2d.close();
9648 init_members();
9649 pthread_mutex_unlock(&omx->c_lock);
9650 }
9651 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009652}
9653
9654OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009655 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009656{
Arun Menon906de572013-06-18 17:01:40 -07009657 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9658 if (!enabled) {
9659 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9660 return eRet;
9661 }
9662 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009663 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009664 omx->is_component_secure());
9665 return OMX_ErrorUnsupportedSetting;
9666 }
9667 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009668 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9669 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009670 buffer_size_req,bytes);
9671 return OMX_ErrorBadParameter;
9672 }
9673 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009674 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009675 return OMX_ErrorInsufficientResources;
9676 }
9677 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9678 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9679 port,appData,omx->drv_ctx.op_buf.buffer_size);
9680 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009681 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009682 return eRet;
9683 }
9684 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309685 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009686 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009687 (temp_bufferHdr - omx->m_out_mem_ptr));
9688 return OMX_ErrorUndefined;
9689 }
9690 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009691#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009692 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9693 buffer_size_req,buffer_alignment_req,
9694 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9695 0);
9696 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9697 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009698 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009699 return OMX_ErrorInsufficientResources;
9700 }
9701 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9702 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009703
Arun Menon906de572013-06-18 17:01:40 -07009704 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009705 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009706 close(pmem_fd[i]);
9707 omx->free_ion_memory(&op_buf_ion_info[i]);
9708 return OMX_ErrorInsufficientResources;
9709 }
9710 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9711 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9712 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009713#endif
Arun Menon906de572013-06-18 17:01:40 -07009714 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9715 m_pmem_info_client[i].offset = 0;
9716 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9717 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9718 m_platform_list_client[i].nEntries = 1;
9719 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9720 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9721 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9722 m_out_mem_ptr_client[i].nFilledLen = 0;
9723 m_out_mem_ptr_client[i].nFlags = 0;
9724 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9725 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9726 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9727 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9728 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9729 m_out_mem_ptr_client[i].pAppPrivate = appData;
9730 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009731 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009732 allocated_count++;
9733 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009734}
9735
9736bool omx_vdec::is_component_secure()
9737{
Arun Menon906de572013-06-18 17:01:40 -07009738 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009739}
9740
9741bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9742{
Arun Menon906de572013-06-18 17:01:40 -07009743 bool status = true;
9744 if (!enabled) {
9745 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9746 dest_color_format = (OMX_COLOR_FORMATTYPE)
9747 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9748 else
9749 status = false;
9750 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009751 if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
9752 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
9753 dest_color_format = ColorFormat;
Arun Menon906de572013-06-18 17:01:40 -07009754 } else
Praveen Chavandb7776f2014-02-06 18:17:25 -08009755 status = false;
Arun Menon906de572013-06-18 17:01:40 -07009756 }
9757 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009758}
Arun Menonbdb80b02013-08-12 17:45:54 -07009759
Arun Menonbdb80b02013-08-12 17:45:54 -07009760void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9761{
9762 int i = 0;
9763 bool buf_present = false;
9764 pthread_mutex_lock(&m_lock);
9765 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9766 //check the buffer fd, offset, uv addr with list contents
9767 //If present increment reference.
9768 if ((out_dynamic_list[i].fd == fd) &&
9769 (out_dynamic_list[i].offset == offset)) {
9770 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009771 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009772 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9773 buf_present = true;
9774 break;
9775 }
9776 }
9777 if (!buf_present) {
9778 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9779 //search for a entry to insert details of the new buffer
9780 if (out_dynamic_list[i].dup_fd == 0) {
9781 out_dynamic_list[i].fd = fd;
9782 out_dynamic_list[i].offset = offset;
9783 out_dynamic_list[i].dup_fd = dup(fd);
9784 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009785 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009786 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9787 break;
9788 }
9789 }
9790 }
9791 pthread_mutex_unlock(&m_lock);
9792}
9793
9794void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9795{
9796 int i = 0;
9797 pthread_mutex_lock(&m_lock);
9798 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9799 //check the buffer fd, offset, uv addr with list contents
9800 //If present decrement reference.
9801 if ((out_dynamic_list[i].fd == fd) &&
9802 (out_dynamic_list[i].offset == offset)) {
9803 out_dynamic_list[i].ref_count--;
9804 if (out_dynamic_list[i].ref_count == 0) {
9805 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009806 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009807 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9808 out_dynamic_list[i].dup_fd = 0;
9809 out_dynamic_list[i].fd = 0;
9810 out_dynamic_list[i].offset = 0;
9811 }
9812 break;
9813 }
9814 }
9815 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009816 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009817 }
9818 pthread_mutex_unlock(&m_lock);
9819}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009820
Arun Menon1fc764f2014-04-17 15:41:27 -07009821OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
9822 unsigned long nMaxFrameHeight)
9823{
9824
9825 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9826 int ret = 0;
9827 unsigned long min_res_buf_count = 0;
9828
9829 eRet = enable_smoothstreaming();
9830 if (eRet != OMX_ErrorNone) {
9831 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
9832 return eRet;
9833 }
9834
9835 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
9836 nMaxFrameWidth,
9837 nMaxFrameHeight);
9838 m_smoothstreaming_mode = true;
9839 m_smoothstreaming_width = nMaxFrameWidth;
9840 m_smoothstreaming_height = nMaxFrameHeight;
9841
9842 //Get upper limit buffer count for min supported resolution
9843 struct v4l2_format fmt;
9844 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9845 fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
9846 fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
9847 fmt.fmt.pix_mp.pixelformat = output_capability;
9848
9849 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9850 if (ret) {
9851 DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
9852 m_decoder_capability.min_height,
9853 m_decoder_capability.min_width);
9854 return OMX_ErrorUnsupportedSetting;
9855 }
9856
9857 eRet = get_buffer_req(&drv_ctx.op_buf);
9858 if (eRet != OMX_ErrorNone) {
9859 DEBUG_PRINT_ERROR("failed to get_buffer_req");
9860 return eRet;
9861 }
9862
9863 min_res_buf_count = drv_ctx.op_buf.mincount;
9864 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
9865 min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
9866
9867 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
9868 m_smoothstreaming_width, m_smoothstreaming_height);
9869 eRet = is_video_session_supported();
9870 if (eRet != OMX_ErrorNone) {
9871 DEBUG_PRINT_ERROR("video session is not supported");
9872 return eRet;
9873 }
9874
9875 //Get upper limit buffer size for max smooth streaming resolution set
9876 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9877 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
9878 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
9879 fmt.fmt.pix_mp.pixelformat = output_capability;
9880 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9881 if (ret) {
9882 DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
9883 return OMX_ErrorUnsupportedSetting;
9884 }
9885
9886 eRet = get_buffer_req(&drv_ctx.op_buf);
9887 if (eRet != OMX_ErrorNone) {
9888 DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
9889 return eRet;
9890 }
9891 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
9892 drv_ctx.op_buf.buffer_size);
9893
9894 drv_ctx.op_buf.mincount = min_res_buf_count;
9895 drv_ctx.op_buf.actualcount = min_res_buf_count;
9896 eRet = set_buffer_req(&drv_ctx.op_buf);
9897 if (eRet != OMX_ErrorNone) {
9898 DEBUG_PRINT_ERROR("failed to set_buffer_req");
9899 return eRet;
9900 }
9901
9902 eRet = get_buffer_req(&drv_ctx.op_buf);
9903 if (eRet != OMX_ErrorNone) {
9904 DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
9905 return eRet;
9906 }
9907 DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
9908 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size);
9909 return eRet;
9910}
9911
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009912#ifdef _MSM8974_
9913void omx_vdec::send_codec_config() {
9914 if (codec_config_flag) {
9915 unsigned p1 = 0; // Parameter - 1
9916 unsigned p2 = 0; // Parameter - 2
9917 unsigned ident = 0;
9918 pthread_mutex_lock(&m_lock);
9919 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9920 while (m_etb_q.m_size) {
9921 m_etb_q.pop_entry(&p1,&p2,&ident);
9922 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9923 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9924 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9925 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9926 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9927 omx_report_error();
9928 }
9929 } else {
9930 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9931 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9932 }
9933 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9934 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9935 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9936 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9937 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9938 omx_report_error ();
9939 }
9940 } else {
9941 pending_input_buffers++;
9942 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9943 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9944 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9945 }
9946 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9947 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9948 (OMX_BUFFERHEADERTYPE *)p1);
9949 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9950 }
9951 }
9952 pthread_mutex_unlock(&m_lock);
9953 }
9954}
9955#endif