blob: b55c35443e581acc2cec39d2648a4a3136c2def4 [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)
Maheshwar Ajja77cd19c2014-06-05 11:23:18 +0530129#define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1))
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700130
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800131#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jia Meng3a3c6492013-12-19 17:16:52 +0800132#define DEFAULT_CONCEAL_COLOR "32896" //0x8080, black by default
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700133
134int debug_level = PRIO_ERROR;
135
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530136static OMX_U32 maxSmoothStreamingWidth = 1920;
137static OMX_U32 maxSmoothStreamingHeight = 1088;
Praveen Chavancf924182013-12-06 23:16:23 -0800138
Shalaj Jain273b3e02012-06-22 19:08:03 -0700139void* async_message_thread (void *input)
140{
Arun Menon906de572013-06-18 17:01:40 -0700141 OMX_BUFFERHEADERTYPE *buffer;
142 struct v4l2_plane plane[VIDEO_MAX_PLANES];
143 struct pollfd pfd;
144 struct v4l2_buffer v4l2_buf;
145 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
146 struct v4l2_event dqevent;
147 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
148 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
149 pfd.fd = omx->drv_ctx.video_driver_fd;
150 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700151 DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
Arun Menon906de572013-06-18 17:01:40 -0700152 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
153 while (1) {
154 rc = poll(&pfd, 1, POLL_TIMEOUT);
155 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700156 DEBUG_PRINT_ERROR("Poll timedout");
Arun Menon906de572013-06-18 17:01:40 -0700157 break;
158 } else if (rc < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700159 DEBUG_PRINT_ERROR("Error while polling: %d", rc);
Arun Menon906de572013-06-18 17:01:40 -0700160 break;
161 }
162 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
163 struct vdec_msginfo vdec_msg;
164 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
165 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
166 v4l2_buf.length = omx->drv_ctx.num_planes;
167 v4l2_buf.m.planes = plane;
168 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
169 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
170 vdec_msg.status_code=VDEC_S_SUCCESS;
171 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
172 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
173 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
174 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
175 (uint64_t)v4l2_buf.timestamp.tv_usec;
176 if (vdec_msg.msgdata.output_frame.len) {
177 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
178 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
179 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
180 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +0530181 vdec_msg.msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
182 vdec_msg.msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
Arun Menon906de572013-06-18 17:01:40 -0700183 }
184 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700185 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700186 break;
187 }
188 }
189 }
190 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
191 struct vdec_msginfo vdec_msg;
192 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
193 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
194 v4l2_buf.length = 1;
195 v4l2_buf.m.planes = plane;
196 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
197 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
198 vdec_msg.status_code=VDEC_S_SUCCESS;
199 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
200 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700201 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700202 break;
203 }
204 }
205 }
206 if (pfd.revents & POLLPRI) {
207 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
208 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
209 struct vdec_msginfo vdec_msg;
210 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
211 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700212 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved insufficient");
Arun Menon906de572013-06-18 17:01:40 -0700213 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700214 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700215 break;
216 }
217 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
218 struct vdec_msginfo vdec_msg;
219 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
220 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700221 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700222 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700223 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700224 break;
225 }
226 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
227 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700228 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700229 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700230 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700231 break;
232 }
233 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700234 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700235 break;
Deepak Verma24720fb2014-01-29 16:57:40 +0530236 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
237 struct vdec_msginfo vdec_msg;
238 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
239 vdec_msg.status_code=VDEC_S_SUCCESS;
240 DEBUG_PRINT_ERROR("HW Overload received");
241 if (omx->async_message_process(input,&vdec_msg) < 0) {
242 DEBUG_PRINT_HIGH("async_message_thread Exited");
243 break;
244 }
Arun Menon906de572013-06-18 17:01:40 -0700245 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
246 struct vdec_msginfo vdec_msg;
Jia Meng1e236c82014-04-03 10:54:39 +0800247 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR;
248 vdec_msg.status_code = VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700249 DEBUG_PRINT_HIGH("SYS Error Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700250 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700251 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700252 break;
253 }
Arun Menon45346052013-11-13 12:40:08 -0800254 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
Arun Menonbdb80b02013-08-12 17:45:54 -0700255 unsigned int *ptr = (unsigned int *)dqevent.u.data;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700256 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700257 omx->buf_ref_remove(ptr[0], ptr[1]);
258 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
259 unsigned int *ptr = (unsigned int *)dqevent.u.data;
260 struct vdec_msginfo vdec_msg;
261
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700262 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700263
264 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
265 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
266 v4l2_buf.length = omx->drv_ctx.num_planes;
267 v4l2_buf.m.planes = plane;
268 v4l2_buf.index = ptr[5];
269 v4l2_buf.flags = 0;
270
271 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
272 vdec_msg.status_code = VDEC_S_SUCCESS;
273 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
274 vdec_msg.msgdata.output_frame.len = 0;
275 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
276 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
277 (uint64_t)ptr[4];
278 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700279 DEBUG_PRINT_HIGH("async_message_thread Exitedn");
Arun Menonbdb80b02013-08-12 17:45:54 -0700280 break;
281 }
282 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700283 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700284 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
Arun Menon906de572013-06-18 17:01:40 -0700285 continue;
286 }
287 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700288 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700289 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700290 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700291}
292
Ashray Kulkarnia97efbc2015-07-15 18:17:23 -0700293void* dec_message_thread(void *input)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700294{
Arun Menon906de572013-06-18 17:01:40 -0700295 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
296 unsigned char id;
297 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700298
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700299 DEBUG_PRINT_HIGH("omx_vdec: message thread start");
Arun Menon906de572013-06-18 17:01:40 -0700300 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
301 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700302
Arun Menon906de572013-06-18 17:01:40 -0700303 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700304
Arun Menon906de572013-06-18 17:01:40 -0700305 if (0 == n) {
306 break;
307 }
308
309 if (1 == n) {
310 omx->process_event_cb(omx, id);
311 }
312 if ((n < 0) && (errno != EINTR)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700313 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
Arun Menon906de572013-06-18 17:01:40 -0700314 break;
315 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700316 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700317 DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700318 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700319}
320
321void post_message(omx_vdec *omx, unsigned char id)
322{
Arun Menon906de572013-06-18 17:01:40 -0700323 int ret_value;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700324 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
Arun Menon906de572013-06-18 17:01:40 -0700325 ret_value = write(omx->m_pipe_out, &id, 1);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700326 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700327}
328
329// omx_cmd_queue destructor
330omx_vdec::omx_cmd_queue::~omx_cmd_queue()
331{
Arun Menon906de572013-06-18 17:01:40 -0700332 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700333}
334
335// omx cmd queue constructor
336omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
337{
338 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
339}
340
341// omx cmd queue insert
342bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
343{
Arun Menon906de572013-06-18 17:01:40 -0700344 bool ret = true;
345 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
346 m_q[m_write].id = id;
347 m_q[m_write].param1 = p1;
348 m_q[m_write].param2 = p2;
349 m_write++;
350 m_size ++;
351 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
352 m_write = 0;
353 }
354 } else {
355 ret = false;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700356 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700357 }
Arun Menon906de572013-06-18 17:01:40 -0700358 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700359}
360
361// omx cmd queue pop
362bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
363{
Arun Menon906de572013-06-18 17:01:40 -0700364 bool ret = true;
365 if (m_size > 0) {
366 *id = m_q[m_read].id;
367 *p1 = m_q[m_read].param1;
368 *p2 = m_q[m_read].param2;
369 // Move the read pointer ahead
370 ++m_read;
371 --m_size;
372 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
373 m_read = 0;
374 }
375 } else {
376 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700377 }
Arun Menon906de572013-06-18 17:01:40 -0700378 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700379}
380
381// Retrieve the first mesg type in the queue
382unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
383{
384 return m_q[m_read].id;
385}
386
387#ifdef _ANDROID_
388omx_vdec::ts_arr_list::ts_arr_list()
389{
Arun Menon906de572013-06-18 17:01:40 -0700390 //initialize timestamps array
391 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700392}
393omx_vdec::ts_arr_list::~ts_arr_list()
394{
Arun Menon906de572013-06-18 17:01:40 -0700395 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700396}
397
398bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
399{
Arun Menon906de572013-06-18 17:01:40 -0700400 bool ret = true;
401 bool duplicate_ts = false;
402 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700403
Arun Menon906de572013-06-18 17:01:40 -0700404 //insert at the first available empty location
405 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
406 if (!m_ts_arr_list[idx].valid) {
407 //found invalid or empty entry, save timestamp
408 m_ts_arr_list[idx].valid = true;
409 m_ts_arr_list[idx].timestamp = ts;
410 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
411 ts, idx);
412 break;
413 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700414 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700415
Arun Menon906de572013-06-18 17:01:40 -0700416 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
417 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
418 ret = false;
419 }
420 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700421}
422
423bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
424{
Arun Menon906de572013-06-18 17:01:40 -0700425 bool ret = true;
426 int min_idx = -1;
427 OMX_TICKS min_ts = 0;
428 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700429
Arun Menon906de572013-06-18 17:01:40 -0700430 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700431
Arun Menon906de572013-06-18 17:01:40 -0700432 if (m_ts_arr_list[idx].valid) {
433 //found valid entry, save index
434 if (min_idx < 0) {
435 //first valid entry
436 min_ts = m_ts_arr_list[idx].timestamp;
437 min_idx = idx;
438 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
439 min_ts = m_ts_arr_list[idx].timestamp;
440 min_idx = idx;
441 }
442 }
443
Shalaj Jain273b3e02012-06-22 19:08:03 -0700444 }
445
Arun Menon906de572013-06-18 17:01:40 -0700446 if (min_idx < 0) {
447 //no valid entries found
448 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
449 ts = 0;
450 ret = false;
451 } else {
452 ts = m_ts_arr_list[min_idx].timestamp;
453 m_ts_arr_list[min_idx].valid = false;
454 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
455 ts, min_idx);
456 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700457
Arun Menon906de572013-06-18 17:01:40 -0700458 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700459
460}
461
462
463bool omx_vdec::ts_arr_list::reset_ts_list()
464{
Arun Menon906de572013-06-18 17:01:40 -0700465 bool ret = true;
466 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700467
Arun Menon906de572013-06-18 17:01:40 -0700468 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
469 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
470 m_ts_arr_list[idx].valid = false;
471 }
472 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700473}
474#endif
475
476// factory function executed by the core to create instances
477void *get_omx_component_factory_fn(void)
478{
Arun Menon906de572013-06-18 17:01:40 -0700479 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700480}
481
482#ifdef _ANDROID_
483#ifdef USE_ION
484VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Mitchel Humpherys2294c232013-12-10 12:14:04 -0800485 ion_user_handle_t handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700486{
Arun Menon906de572013-06-18 17:01:40 -0700487 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700488}
489#else
490VideoHeap::VideoHeap(int fd, size_t size, void* base)
491{
492 // dup file descriptor, map once, use pmem
493 init(dup(fd), base, size, 0 , MEM_DEVICE);
494}
495#endif
496#endif // _ANDROID_
497/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700498 FUNCTION
499 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700500
Arun Menon906de572013-06-18 17:01:40 -0700501 DESCRIPTION
502 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700503
Arun Menon906de572013-06-18 17:01:40 -0700504 PARAMETERS
505 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700506
Arun Menon906de572013-06-18 17:01:40 -0700507 RETURN VALUE
508 None.
509 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800510omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700511 m_state(OMX_StateInvalid),
512 m_app_data(NULL),
513 m_inp_mem_ptr(NULL),
514 m_out_mem_ptr(NULL),
Arun Menon906de572013-06-18 17:01:40 -0700515 input_flush_progress (false),
516 output_flush_progress (false),
517 input_use_buffer (false),
518 output_use_buffer (false),
519 ouput_egl_buffers(false),
520 m_use_output_pmem(OMX_FALSE),
521 m_out_mem_region_smi(OMX_FALSE),
522 m_out_pvt_entry_pmem(OMX_FALSE),
523 pending_input_buffers(0),
524 pending_output_buffers(0),
525 m_out_bm_count(0),
526 m_inp_bm_count(0),
527 m_inp_bPopulated(OMX_FALSE),
528 m_out_bPopulated(OMX_FALSE),
529 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700530#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700531 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700532#endif
Arun Menon906de572013-06-18 17:01:40 -0700533 m_inp_bEnabled(OMX_TRUE),
534 m_out_bEnabled(OMX_TRUE),
535 m_in_alloc_cnt(0),
536 m_platform_list(NULL),
537 m_platform_entry(NULL),
538 m_pmem_info(NULL),
539 arbitrary_bytes (true),
540 psource_frame (NULL),
541 pdest_frame (NULL),
542 m_inp_heap_ptr (NULL),
543 m_phdr_pmem_ptr(NULL),
544 m_heap_inp_bm_count (0),
545 codec_type_parse ((codec_type)0),
546 first_frame_meta (true),
547 frame_count (0),
548 nal_count (0),
549 nal_length(0),
550 look_ahead_nal (false),
551 first_frame(0),
552 first_buffer(NULL),
553 first_frame_size (0),
554 m_device_file_ptr(NULL),
555 m_vc1_profile((vc1_profile_type)0),
Arun Menon906de572013-06-18 17:01:40 -0700556 h264_last_au_ts(LLONG_MAX),
557 h264_last_au_flags(0),
Surajit Podderd2644d52013-08-28 17:59:06 +0530558 m_disp_hor_size(0),
559 m_disp_vert_size(0),
Arun Menon906de572013-06-18 17:01:40 -0700560 prev_ts(LLONG_MAX),
Ashray Kulkarni6ecd0372015-09-02 17:51:20 -0700561 prev_ts_actual(LLONG_MAX),
Arun Menon906de572013-06-18 17:01:40 -0700562 rst_prev_ts(true),
563 frm_int(0),
Arun Menon906de572013-06-18 17:01:40 -0700564 in_reconfig(false),
565 m_display_id(NULL),
566 h264_parser(NULL),
567 client_extradata(0),
568 m_reject_avc_1080p_mp (0),
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +0530569 m_other_extradata(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700570#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700571 m_enable_android_native_buffers(OMX_FALSE),
572 m_use_android_native_buffers(OMX_FALSE),
573 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700574#endif
Arun Menon906de572013-06-18 17:01:40 -0700575 m_desc_buffer_ptr(NULL),
576 secure_mode(false),
Surajit Podderd2644d52013-08-28 17:59:06 +0530577 m_profile(0),
vivek mehtaa75c69f2014-01-10 21:50:37 -0800578 client_set_fps(false),
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -0700579 m_last_rendered_TS(-1),
580 m_queued_codec_config_count(0)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700581{
Arun Menon906de572013-06-18 17:01:40 -0700582 /* Assumption is that , to begin with , we have all the frames with decoder */
583 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700584 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700585#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700586 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700587 property_get("vidc.debug.level", property_value, "0");
588 debug_level = atoi(property_value);
589 property_value[0] = '\0';
590
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700591 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
592
Arun Menon906de572013-06-18 17:01:40 -0700593 property_get("vidc.dec.debug.perf", property_value, "0");
594 perf_flag = atoi(property_value);
595 if (perf_flag) {
596 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
597 dec_time.start();
598 proc_frms = latency = 0;
599 }
600 prev_n_filled_len = 0;
601 property_value[0] = '\0';
602 property_get("vidc.dec.debug.ts", property_value, "0");
603 m_debug_timestamp = atoi(property_value);
604 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
605 if (m_debug_timestamp) {
606 time_stamp_dts.set_timestamp_reorder_mode(true);
607 time_stamp_dts.enable_debug_print(true);
608 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700609
Arun Menon906de572013-06-18 17:01:40 -0700610 property_value[0] = '\0';
611 property_get("vidc.dec.debug.concealedmb", property_value, "0");
612 m_debug_concealedmb = atoi(property_value);
613 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700614
Arun Menon906de572013-06-18 17:01:40 -0700615 property_value[0] = '\0';
616 property_get("vidc.dec.profile.check", property_value, "0");
617 m_reject_avc_1080p_mp = atoi(property_value);
618 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530619
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700620 property_value[0] = '\0';
621 property_get("vidc.dec.log.in", property_value, "0");
622 m_debug.in_buffer_log = atoi(property_value);
623
624 property_value[0] = '\0';
625 property_get("vidc.dec.log.out", property_value, "0");
626 m_debug.out_buffer_log = atoi(property_value);
627 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
628
629 property_value[0] = '\0';
630 property_get("vidc.log.loc", property_value, "");
631 if (*property_value)
632 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
vivek mehta79cff222014-01-22 12:17:07 -0800633
634 property_value[0] = '\0';
635 property_get("vidc.dec.120fps.enabled", property_value, "0");
636
637 //if this feature is not enabled then reset this value -ve
638 if(atoi(property_value)) {
639 DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
640 m_last_rendered_TS = 0;
641 }
642
Shalaj Jain273b3e02012-06-22 19:08:03 -0700643#endif
Arun Menon906de572013-06-18 17:01:40 -0700644 memset(&m_cmp,0,sizeof(m_cmp));
645 memset(&m_cb,0,sizeof(m_cb));
646 memset (&drv_ctx,0,sizeof(drv_ctx));
647 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
648 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
649 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +0530650 memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
Arun Menon906de572013-06-18 17:01:40 -0700651 m_demux_entries = 0;
652 msg_thread_id = 0;
653 async_thread_id = 0;
654 msg_thread_created = false;
655 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700656#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700657 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700658#endif
Arun Menon906de572013-06-18 17:01:40 -0700659 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Maheshwar Ajjad2df2182013-10-24 19:20:34 +0530660 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -0700661 drv_ctx.timestamp_adjust = false;
662 drv_ctx.video_driver_fd = -1;
663 m_vendor_config.pData = NULL;
664 pthread_mutex_init(&m_lock, NULL);
665 pthread_mutex_init(&c_lock, NULL);
666 sem_init(&m_cmd_lock,0,0);
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -0700667 sem_init(&m_safe_flush, 0, 0);
Arun Menon906de572013-06-18 17:01:40 -0700668 streaming[CAPTURE_PORT] =
669 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700670#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700671 char extradata_value[PROPERTY_VALUE_MAX] = {0};
672 property_get("vidc.dec.debug.extradata", extradata_value, "0");
673 m_debug_extradata = atoi(extradata_value);
674 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700675#endif
Arun Menon906de572013-06-18 17:01:40 -0700676 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
677 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700678 dynamic_buf_mode = false;
679 out_dynamic_list = NULL;
Praveen Chavane78460c2013-12-06 23:16:04 -0800680 is_down_scalar_enabled = false;
Praveen Chavancf924182013-12-06 23:16:23 -0800681 m_smoothstreaming_mode = false;
682 m_smoothstreaming_width = 0;
683 m_smoothstreaming_height = 0;
Deepak Vermaa2efdb12013-12-26 12:30:05 +0530684 is_q6_platform = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700685}
686
Vinay Kalia85793762012-06-14 19:12:34 -0700687static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700688 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
689 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
690 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700691 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
692 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
Arun Menon906de572013-06-18 17:01:40 -0700693 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
Jia Meng1e236c82014-04-03 10:54:39 +0800694 V4L2_EVENT_MSM_VIDC_SYS_ERROR,
695 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD
Vinay Kalia85793762012-06-14 19:12:34 -0700696};
697
698static OMX_ERRORTYPE subscribe_to_events(int fd)
699{
Arun Menon906de572013-06-18 17:01:40 -0700700 OMX_ERRORTYPE eRet = OMX_ErrorNone;
701 struct v4l2_event_subscription sub;
702 int array_sz = sizeof(event_type)/sizeof(int);
703 int i,rc;
704 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700705 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700706 return OMX_ErrorBadParameter;
707 }
Vinay Kalia85793762012-06-14 19:12:34 -0700708
Arun Menon906de572013-06-18 17:01:40 -0700709 for (i = 0; i < array_sz; ++i) {
710 memset(&sub, 0, sizeof(sub));
711 sub.type = event_type[i];
712 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
713 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700714 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700715 break;
716 }
717 }
718 if (i < array_sz) {
719 for (--i; i >=0 ; i--) {
720 memset(&sub, 0, sizeof(sub));
721 sub.type = event_type[i];
722 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
723 if (rc)
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700724 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700725 }
726 eRet = OMX_ErrorNotImplemented;
727 }
728 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700729}
730
731
732static OMX_ERRORTYPE unsubscribe_to_events(int fd)
733{
Arun Menon906de572013-06-18 17:01:40 -0700734 OMX_ERRORTYPE eRet = OMX_ErrorNone;
735 struct v4l2_event_subscription sub;
736 int array_sz = sizeof(event_type)/sizeof(int);
737 int i,rc;
738 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700739 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700740 return OMX_ErrorBadParameter;
741 }
Vinay Kalia85793762012-06-14 19:12:34 -0700742
Arun Menon906de572013-06-18 17:01:40 -0700743 for (i = 0; i < array_sz; ++i) {
744 memset(&sub, 0, sizeof(sub));
745 sub.type = event_type[i];
746 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
747 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700748 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700749 break;
750 }
751 }
752 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700753}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700754
755/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700756 FUNCTION
757 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700758
Arun Menon906de572013-06-18 17:01:40 -0700759 DESCRIPTION
760 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700761
Arun Menon906de572013-06-18 17:01:40 -0700762 PARAMETERS
763 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700764
Arun Menon906de572013-06-18 17:01:40 -0700765 RETURN VALUE
766 None.
767 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700768omx_vdec::~omx_vdec()
769{
Arun Menon906de572013-06-18 17:01:40 -0700770 m_pmem_info = NULL;
771 struct v4l2_decoder_cmd dec;
772 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
773 if (m_pipe_in) close(m_pipe_in);
774 if (m_pipe_out) close(m_pipe_out);
775 m_pipe_in = -1;
776 m_pipe_out = -1;
777 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
778 if (msg_thread_created)
779 pthread_join(msg_thread_id,NULL);
780 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
781 dec.cmd = V4L2_DEC_CMD_STOP;
782 if (drv_ctx.video_driver_fd >=0 ) {
783 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700784 DEBUG_PRINT_ERROR("STOP Command failed");
Arun Menon906de572013-06-18 17:01:40 -0700785 }
786 if (async_thread_created)
787 pthread_join(async_thread_id,NULL);
788 unsubscribe_to_events(drv_ctx.video_driver_fd);
789 close(drv_ctx.video_driver_fd);
790 pthread_mutex_destroy(&m_lock);
791 pthread_mutex_destroy(&c_lock);
792 sem_destroy(&m_cmd_lock);
793 if (perf_flag) {
794 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
795 dec_time.end();
796 }
797 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700798}
799
Arun Menon906de572013-06-18 17:01:40 -0700800int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
801{
802 struct v4l2_requestbuffers bufreq;
803 int rc = 0;
804 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
805 bufreq.memory = V4L2_MEMORY_USERPTR;
806 bufreq.count = 0;
807 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
808 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530809 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
810 bufreq.memory = V4L2_MEMORY_USERPTR;
811 bufreq.count = 0;
812 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
813 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700814 }
815 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700816}
817
Shalaj Jain273b3e02012-06-22 19:08:03 -0700818/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700819 FUNCTION
820 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700821
Arun Menon906de572013-06-18 17:01:40 -0700822 DESCRIPTION
823 IL Client callbacks are generated through this routine. The decoder
824 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700825
Arun Menon906de572013-06-18 17:01:40 -0700826 PARAMETERS
827 ctxt -- Context information related to the self.
828 id -- Event identifier. This could be any of the following:
829 1. Command completion event
830 2. Buffer done callback event
831 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700832
Arun Menon906de572013-06-18 17:01:40 -0700833 RETURN VALUE
834 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700835
Arun Menon906de572013-06-18 17:01:40 -0700836 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700837void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
838{
Arun Menon906de572013-06-18 17:01:40 -0700839 signed p1; // Parameter - 1
840 signed p2; // Parameter - 2
841 unsigned ident;
842 unsigned qsize=0; // qsize
843 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700844
Arun Menon906de572013-06-18 17:01:40 -0700845 if (!pThis) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700846 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
Arun Menon906de572013-06-18 17:01:40 -0700847 __func__);
848 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700849 }
850
Arun Menon906de572013-06-18 17:01:40 -0700851 // Protect the shared queue data structure
852 do {
853 /*Read the message id's from the queue*/
854 pthread_mutex_lock(&pThis->m_lock);
855 qsize = pThis->m_cmd_q.m_size;
856 if (qsize) {
857 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700858 }
Arun Menon906de572013-06-18 17:01:40 -0700859
860 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
861 qsize = pThis->m_ftb_q.m_size;
862 if (qsize) {
863 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
864 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700865 }
Arun Menon906de572013-06-18 17:01:40 -0700866
867 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
868 qsize = pThis->m_etb_q.m_size;
869 if (qsize) {
870 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
871 }
872 }
873 pthread_mutex_unlock(&pThis->m_lock);
874
875 /*process message if we have one*/
876 if (qsize > 0) {
877 id = ident;
878 switch (id) {
879 case OMX_COMPONENT_GENERATE_EVENT:
880 if (pThis->m_cb.EventHandler) {
881 switch (p1) {
882 case OMX_CommandStateSet:
883 pThis->m_state = (OMX_STATETYPE) p2;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700884 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
Arun Menon906de572013-06-18 17:01:40 -0700885 pThis->m_state);
886 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
887 OMX_EventCmdComplete, p1, p2, NULL);
888 break;
889
890 case OMX_EventError:
891 if (p2 == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700892 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
Arun Menon906de572013-06-18 17:01:40 -0700893 pThis->m_state = (OMX_STATETYPE) p2;
894 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
895 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
896 } else if (p2 == OMX_ErrorHardware) {
897 pThis->omx_report_error();
898 } else {
899 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
900 OMX_EventError, p2, (OMX_U32)NULL, NULL );
901 }
902 break;
903
904 case OMX_CommandPortDisable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700905 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700906 if (BITMASK_PRESENT(&pThis->m_flags,
907 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
908 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
909 break;
910 }
911 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
912 OMX_ERRORTYPE eRet = OMX_ErrorNone;
913 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
914 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700915 DEBUG_PRINT_HIGH("Failed to release output buffers");
Arun Menon906de572013-06-18 17:01:40 -0700916 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
917 pThis->in_reconfig = false;
918 if (eRet != OMX_ErrorNone) {
919 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
920 pThis->omx_report_error();
921 break;
922 }
923 }
924 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
925 OMX_EventCmdComplete, p1, p2, NULL );
926 break;
927 case OMX_CommandPortEnable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700928 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700929 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
930 OMX_EventCmdComplete, p1, p2, NULL );
931 break;
932
933 default:
934 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
935 OMX_EventCmdComplete, p1, p2, NULL );
936 break;
937
938 }
939 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700940 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Arun Menon906de572013-06-18 17:01:40 -0700941 }
942 break;
943 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
944 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
945 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700946 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
Arun Menon906de572013-06-18 17:01:40 -0700947 pThis->omx_report_error ();
948 }
949 break;
Jia Meng1e236c82014-04-03 10:54:39 +0800950 case OMX_COMPONENT_GENERATE_ETB: {
951 OMX_ERRORTYPE iret;
952 iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
953 if (iret == OMX_ErrorInsufficientResources) {
954 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
955 pThis->omx_report_hw_overload ();
956 } else if (iret != OMX_ErrorNone) {
957 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
958 pThis->omx_report_error ();
959 }
Arun Menon906de572013-06-18 17:01:40 -0700960 }
961 break;
962
963 case OMX_COMPONENT_GENERATE_FTB:
964 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
965 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700966 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700967 pThis->omx_report_error ();
968 }
969 break;
970
971 case OMX_COMPONENT_GENERATE_COMMAND:
972 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
973 (OMX_U32)p2,(OMX_PTR)NULL);
974 break;
975
976 case OMX_COMPONENT_GENERATE_EBD:
977
978 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700979 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700980 pThis->omx_report_error ();
981 } else {
982 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
Arun Menon906de572013-06-18 17:01:40 -0700983 pThis->time_stamp_dts.remove_time_stamp(
984 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
985 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
986 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -0700987 }
Deva Ramasubramanian02b0d882014-04-03 14:58:50 -0700988
Arun Menon906de572013-06-18 17:01:40 -0700989 if ( pThis->empty_buffer_done(&pThis->m_cmp,
990 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700991 DEBUG_PRINT_ERROR("empty_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700992 pThis->omx_report_error ();
993 }
Arun Menon906de572013-06-18 17:01:40 -0700994 }
995 break;
996 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
997 int64_t *timestamp = (int64_t *)p1;
998 if (p1) {
999 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
1000 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
1001 ?true:false);
1002 free(timestamp);
1003 }
1004 }
1005 break;
1006 case OMX_COMPONENT_GENERATE_FBD:
1007 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001008 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
Arun Menon906de572013-06-18 17:01:40 -07001009 pThis->omx_report_error ();
1010 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
1011 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001012 DEBUG_PRINT_ERROR("fill_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -07001013 pThis->omx_report_error ();
1014 }
1015 break;
1016
1017 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001018 DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001019 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001020 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001021 } else {
1022 pThis->execute_input_flush();
1023 if (pThis->m_cb.EventHandler) {
1024 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001025 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
Arun Menon906de572013-06-18 17:01:40 -07001026 pThis->omx_report_error ();
1027 } else {
1028 /*Check if we need generate event for Flush done*/
1029 if (BITMASK_PRESENT(&pThis->m_flags,
1030 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
1031 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001032 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
Arun Menon906de572013-06-18 17:01:40 -07001033 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1034 OMX_EventCmdComplete,OMX_CommandFlush,
1035 OMX_CORE_INPUT_PORT_INDEX,NULL );
1036 }
1037 if (BITMASK_PRESENT(&pThis->m_flags,
1038 OMX_COMPONENT_IDLE_PENDING)) {
1039 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001040 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
Arun Menon906de572013-06-18 17:01:40 -07001041 pThis->omx_report_error ();
1042 } else {
1043 pThis->streaming[OUTPUT_PORT] = false;
1044 }
1045 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001046 DEBUG_PRINT_LOW("Input flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001047 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1048 OMX_COMPONENT_GENERATE_STOP_DONE);
1049 }
1050 }
1051 }
1052 } else {
1053 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1054 }
1055 }
1056 break;
1057
1058 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001059 DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001060 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001061 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001062 } else {
1063 pThis->execute_output_flush();
1064 if (pThis->m_cb.EventHandler) {
1065 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001066 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
Arun Menon906de572013-06-18 17:01:40 -07001067 pThis->omx_report_error ();
1068 } else {
1069 /*Check if we need generate event for Flush done*/
1070 if (BITMASK_PRESENT(&pThis->m_flags,
1071 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001072 DEBUG_PRINT_LOW("Notify Output Flush done");
Arun Menon906de572013-06-18 17:01:40 -07001073 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1074 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1075 OMX_EventCmdComplete,OMX_CommandFlush,
1076 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1077 }
1078 if (BITMASK_PRESENT(&pThis->m_flags,
1079 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001080 DEBUG_PRINT_LOW("Internal flush complete");
Arun Menon906de572013-06-18 17:01:40 -07001081 BITMASK_CLEAR (&pThis->m_flags,
1082 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1083 if (BITMASK_PRESENT(&pThis->m_flags,
1084 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1085 pThis->post_event(OMX_CommandPortDisable,
1086 OMX_CORE_OUTPUT_PORT_INDEX,
1087 OMX_COMPONENT_GENERATE_EVENT);
1088 BITMASK_CLEAR (&pThis->m_flags,
1089 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
Praneeth Paladugub52072a2013-08-23 13:54:43 -07001090 BITMASK_CLEAR (&pThis->m_flags,
1091 OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Arun Menon906de572013-06-18 17:01:40 -07001092
1093 }
1094 }
1095
1096 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1097 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001098 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
Arun Menon906de572013-06-18 17:01:40 -07001099 pThis->omx_report_error ();
1100 break;
1101 }
1102 pThis->streaming[CAPTURE_PORT] = false;
1103 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001104 DEBUG_PRINT_LOW("Output flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001105 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1106 OMX_COMPONENT_GENERATE_STOP_DONE);
1107 }
1108 }
1109 }
1110 } else {
1111 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1112 }
1113 }
1114 break;
1115
1116 case OMX_COMPONENT_GENERATE_START_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001117 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001118
1119 if (pThis->m_cb.EventHandler) {
1120 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001121 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
Arun Menon906de572013-06-18 17:01:40 -07001122 pThis->omx_report_error ();
1123 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001124 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001125 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001126 DEBUG_PRINT_LOW("Move to executing");
Arun Menon906de572013-06-18 17:01:40 -07001127 // Send the callback now
1128 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1129 pThis->m_state = OMX_StateExecuting;
1130 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1131 OMX_EventCmdComplete,OMX_CommandStateSet,
1132 OMX_StateExecuting, NULL);
1133 } else if (BITMASK_PRESENT(&pThis->m_flags,
1134 OMX_COMPONENT_PAUSE_PENDING)) {
1135 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1136 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001137 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
Arun Menon906de572013-06-18 17:01:40 -07001138 pThis->omx_report_error ();
1139 }
1140 }
1141 }
1142 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001143 DEBUG_PRINT_LOW("Event Handler callback is NULL");
Arun Menon906de572013-06-18 17:01:40 -07001144 }
1145 break;
1146
1147 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001148 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001149 if (pThis->m_cb.EventHandler) {
1150 if (p2 != VDEC_S_SUCCESS) {
1151 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1152 pThis->omx_report_error ();
1153 } else {
1154 pThis->complete_pending_buffer_done_cbs();
1155 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001156 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
Arun Menon906de572013-06-18 17:01:40 -07001157 //Send the callback now
1158 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1159 pThis->m_state = OMX_StatePause;
1160 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1161 OMX_EventCmdComplete,OMX_CommandStateSet,
1162 OMX_StatePause, NULL);
1163 }
1164 }
1165 } else {
1166 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1167 }
1168
1169 break;
1170
1171 case OMX_COMPONENT_GENERATE_RESUME_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001172 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001173 if (pThis->m_cb.EventHandler) {
1174 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001175 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
Arun Menon906de572013-06-18 17:01:40 -07001176 pThis->omx_report_error ();
1177 } else {
1178 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001179 DEBUG_PRINT_LOW("Moving the decoder to execute state");
Arun Menon906de572013-06-18 17:01:40 -07001180 // Send the callback now
1181 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1182 pThis->m_state = OMX_StateExecuting;
1183 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1184 OMX_EventCmdComplete,OMX_CommandStateSet,
1185 OMX_StateExecuting,NULL);
1186 }
1187 }
1188 } else {
1189 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1190 }
1191
1192 break;
1193
1194 case OMX_COMPONENT_GENERATE_STOP_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001195 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001196 if (pThis->m_cb.EventHandler) {
1197 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001198 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
Arun Menon906de572013-06-18 17:01:40 -07001199 pThis->omx_report_error ();
1200 } else {
1201 pThis->complete_pending_buffer_done_cbs();
1202 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001203 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001204 // Send the callback now
1205 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1206 pThis->m_state = OMX_StateIdle;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001207 DEBUG_PRINT_LOW("Move to Idle State");
Arun Menon906de572013-06-18 17:01:40 -07001208 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1209 OMX_EventCmdComplete,OMX_CommandStateSet,
1210 OMX_StateIdle,NULL);
1211 }
1212 }
1213 } else {
1214 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1215 }
1216
1217 break;
1218
1219 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
Arun Menon906de572013-06-18 17:01:40 -07001220 if (p2 == OMX_IndexParamPortDefinition) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301221 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07001222 pThis->in_reconfig = true;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301223
1224 } else if (p2 == OMX_IndexConfigCommonOutputCrop) {
1225 DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301226
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301227 /* Check if resolution is changed in smooth streaming mode */
1228 if (pThis->m_smoothstreaming_mode &&
1229 (pThis->framesize.nWidth !=
1230 pThis->drv_ctx.video_resolution.frame_width) ||
1231 (pThis->framesize.nHeight !=
1232 pThis->drv_ctx.video_resolution.frame_height)) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301233
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301234 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
1235 pThis->framesize.nWidth,
1236 pThis->framesize.nHeight,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301237 pThis->drv_ctx.video_resolution.frame_width,
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301238 pThis->drv_ctx.video_resolution.frame_height);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301239
1240 /* Update new resolution */
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301241 pThis->framesize.nWidth =
1242 pThis->drv_ctx.video_resolution.frame_width;
1243 pThis->framesize.nHeight =
1244 pThis->drv_ctx.video_resolution.frame_height;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05301245
1246 /* Update C2D with new resolution */
1247 if (!pThis->client_buffers.update_buffer_req()) {
1248 DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
1249 }
1250 }
1251
1252 /* Update new crop information */
1253 pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
1254 pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
1255 pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
1256 pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
1257
1258 /* Validate the new crop information */
1259 if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
1260 pThis->drv_ctx.video_resolution.frame_width) {
1261
1262 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
1263 pThis->rectangle.nLeft, pThis->rectangle.nWidth,
1264 pThis->drv_ctx.video_resolution.frame_width);
1265 pThis->rectangle.nLeft = 0;
1266
1267 if (pThis->rectangle.nWidth >
1268 pThis->drv_ctx.video_resolution.frame_width) {
1269
1270 DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
1271 pThis->rectangle.nWidth,
1272 pThis->drv_ctx.video_resolution.frame_width);
1273 pThis->rectangle.nWidth =
1274 pThis->drv_ctx.video_resolution.frame_width;
1275 }
1276 }
1277 if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
1278 pThis->drv_ctx.video_resolution.frame_height) {
1279
1280 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
1281 pThis->rectangle.nTop, pThis->rectangle.nHeight,
1282 pThis->drv_ctx.video_resolution.frame_height);
1283 pThis->rectangle.nTop = 0;
1284
1285 if (pThis->rectangle.nHeight >
1286 pThis->drv_ctx.video_resolution.frame_height) {
1287
1288 DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
1289 pThis->rectangle.nHeight,
1290 pThis->drv_ctx.video_resolution.frame_height);
1291 pThis->rectangle.nHeight =
1292 pThis->drv_ctx.video_resolution.frame_height;
1293 }
1294 }
1295 DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
1296 pThis->rectangle.nLeft, pThis->rectangle.nTop,
1297 pThis->rectangle.nWidth, pThis->rectangle.nHeight);
1298 } else {
1299 DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
1300 break;
Arun Menon906de572013-06-18 17:01:40 -07001301 }
1302 if (pThis->m_cb.EventHandler) {
1303 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1304 OMX_EventPortSettingsChanged, p1, p2, NULL );
1305 } else {
1306 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1307 }
Arun Menon906de572013-06-18 17:01:40 -07001308 break;
1309
1310 case OMX_COMPONENT_GENERATE_EOS_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001311 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001312 if (pThis->m_cb.EventHandler) {
1313 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1314 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1315 } else {
1316 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1317 }
1318 pThis->prev_ts = LLONG_MAX;
1319 pThis->rst_prev_ts = true;
1320 break;
1321
1322 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001323 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
Arun Menon906de572013-06-18 17:01:40 -07001324 pThis->omx_report_error ();
1325 break;
1326
1327 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001328 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
Arun Menon906de572013-06-18 17:01:40 -07001329 pThis->omx_report_unsupported_setting();
1330 break;
1331
Deepak Verma24720fb2014-01-29 16:57:40 +05301332 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
1333 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
1334 pThis->omx_report_hw_overload();
1335 break;
1336
Arun Menon906de572013-06-18 17:01:40 -07001337 default:
1338 break;
1339 }
1340 }
1341 pthread_mutex_lock(&pThis->m_lock);
1342 qsize = pThis->m_cmd_q.m_size;
1343 if (pThis->m_state != OMX_StatePause)
1344 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1345 pthread_mutex_unlock(&pThis->m_lock);
1346 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001347
1348}
1349
Vinay Kaliab9e98102013-04-02 19:31:43 -07001350int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001351{
Arun Menon906de572013-06-18 17:01:40 -07001352 int format_changed = 0;
Surajit Podderd2644d52013-08-28 17:59:06 +05301353 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1354 (width != (int)drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001355 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
Arun Menon906de572013-06-18 17:01:40 -07001356 width, drv_ctx.video_resolution.frame_width,
1357 height,drv_ctx.video_resolution.frame_height);
1358 format_changed = 1;
1359 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001360 drv_ctx.video_resolution.frame_height = height;
1361 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001362 drv_ctx.video_resolution.scan_lines = scan_lines;
1363 drv_ctx.video_resolution.stride = stride;
Pushkaraj Patil41588352014-02-25 20:51:34 +05301364 if(!is_down_scalar_enabled) {
1365 rectangle.nLeft = 0;
1366 rectangle.nTop = 0;
1367 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1368 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
1369 }
Arun Menon906de572013-06-18 17:01:40 -07001370 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001371}
1372
Arun Menon6836ba02013-02-19 20:37:40 -08001373OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1374{
Arun Menon906de572013-06-18 17:01:40 -07001375 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1376 OMX_MAX_STRINGNAME_SIZE) &&
1377 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1378 m_decoder_capability.max_width = 1280;
1379 m_decoder_capability.max_height = 720;
1380 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1381 }
Arun Menon888aa852013-05-30 11:24:42 -07001382
Arun Menon906de572013-06-18 17:01:40 -07001383 if ((drv_ctx.video_resolution.frame_width *
1384 drv_ctx.video_resolution.frame_height >
1385 m_decoder_capability.max_width *
1386 m_decoder_capability.max_height) ||
1387 (drv_ctx.video_resolution.frame_width*
1388 drv_ctx.video_resolution.frame_height <
1389 m_decoder_capability.min_width *
1390 m_decoder_capability.min_height)) {
1391 DEBUG_PRINT_ERROR(
1392 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1393 drv_ctx.video_resolution.frame_width,
1394 drv_ctx.video_resolution.frame_height,
1395 m_decoder_capability.min_width,
1396 m_decoder_capability.min_height,
1397 m_decoder_capability.max_width,
1398 m_decoder_capability.max_height);
1399 return OMX_ErrorUnsupportedSetting;
1400 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001401 DEBUG_PRINT_HIGH("video session supported");
Arun Menon906de572013-06-18 17:01:40 -07001402 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001403}
1404
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001405int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1406{
1407 if (m_debug.in_buffer_log && !m_debug.infile) {
1408 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1409 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1410 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1411 }
1412 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1413 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); }
1414 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1415 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
1416 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1417 }
1418 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
1419 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1420 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1421 }
1422 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1423 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1424 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1425 }
1426 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1427 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1428 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1429 }
1430 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1431 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1432 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1433 }
1434 m_debug.infile = fopen (m_debug.infile_name, "ab");
1435 if (!m_debug.infile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001436 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001437 m_debug.infile_name[0] = '\0';
1438 return -1;
1439 }
1440 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1441 struct ivf_file_header {
1442 OMX_U8 signature[4]; //='DKIF';
1443 OMX_U8 version ; //= 0;
1444 OMX_U8 headersize ; //= 32;
1445 OMX_U32 FourCC;
1446 OMX_U8 width;
1447 OMX_U8 height;
1448 OMX_U32 rate;
1449 OMX_U32 scale;
1450 OMX_U32 length;
1451 OMX_U8 unused[4];
1452 } file_header;
1453
1454 memset((void *)&file_header,0,sizeof(file_header));
1455 file_header.signature[0] = 'D';
1456 file_header.signature[1] = 'K';
1457 file_header.signature[2] = 'I';
1458 file_header.signature[3] = 'F';
1459 file_header.version = 0;
1460 file_header.headersize = 32;
1461 file_header.FourCC = 0x30385056;
1462 fwrite((const char *)&file_header,
1463 sizeof(file_header),1,m_debug.infile);
1464 }
1465 }
1466 if (m_debug.infile && buffer_addr && buffer_len) {
1467 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1468 struct vp8_ivf_frame_header {
1469 OMX_U32 framesize;
1470 OMX_U32 timestamp_lo;
1471 OMX_U32 timestamp_hi;
1472 } vp8_frame_header;
1473 vp8_frame_header.framesize = buffer_len;
1474 /* Currently FW doesn't use timestamp values */
1475 vp8_frame_header.timestamp_lo = 0;
1476 vp8_frame_header.timestamp_hi = 0;
1477 fwrite((const char *)&vp8_frame_header,
1478 sizeof(vp8_frame_header),1,m_debug.infile);
1479 }
1480 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1481 }
1482 return 0;
1483}
1484
1485int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1486 if (m_debug.out_buffer_log && !m_debug.outfile) {
1487 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1488 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1489 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1490 if (!m_debug.outfile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001491 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001492 m_debug.outfile_name[0] = '\0';
1493 return -1;
1494 }
1495 }
1496 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1497 int buf_index = buffer - m_out_mem_ptr;
1498 int stride = drv_ctx.video_resolution.stride;
1499 int scanlines = drv_ctx.video_resolution.scan_lines;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301500 if (m_smoothstreaming_mode) {
1501 stride = drv_ctx.video_resolution.frame_width;
1502 scanlines = drv_ctx.video_resolution.frame_height;
1503 stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
1504 scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
1505 }
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001506 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1507 unsigned i;
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301508 DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
1509 drv_ctx.video_resolution.frame_width,
1510 drv_ctx.video_resolution.frame_height, stride, scanlines);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001511 int bytes_written = 0;
1512 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1513 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1514 temp += stride;
1515 }
1516 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1517 int stride_c = stride;
1518 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1519 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1520 temp += stride_c;
1521 }
1522 }
1523 return 0;
1524}
1525
Shalaj Jain273b3e02012-06-22 19:08:03 -07001526/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001527 FUNCTION
1528 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001529
Arun Menon906de572013-06-18 17:01:40 -07001530 DESCRIPTION
1531 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001532
Arun Menon906de572013-06-18 17:01:40 -07001533 PARAMETERS
1534 ctxt -- Context information related to the self.
1535 id -- Event identifier. This could be any of the following:
1536 1. Command completion event
1537 2. Buffer done callback event
1538 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001539
Arun Menon906de572013-06-18 17:01:40 -07001540 RETURN VALUE
1541 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001542
Arun Menon906de572013-06-18 17:01:40 -07001543 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001544OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1545{
1546
Arun Menon906de572013-06-18 17:01:40 -07001547 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1548 struct v4l2_fmtdesc fdesc;
1549 struct v4l2_format fmt;
1550 struct v4l2_requestbuffers bufreq;
1551 struct v4l2_control control;
1552 struct v4l2_frmsizeenum frmsize;
1553 unsigned int alignment = 0,buffer_size = 0;
1554 int fds[2];
1555 int r,ret=0;
1556 bool codec_ambiguous = false;
Praveen Chavan00ec0ce2015-05-18 09:44:20 -07001557 OMX_STRING device_name = (OMX_STRING)"/dev/video32";
Jia Meng3a3c6492013-12-19 17:16:52 +08001558 char property_value[PROPERTY_VALUE_MAX] = {0};
Sachin Shahc82a18f2013-03-29 14:45:38 -07001559
1560#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001561 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001562 property_get("ro.board.platform", platform_name, "0");
1563 if (!strncmp(platform_name, "msm8610", 7)) {
Balamurugan Alagarsamy1693e592015-07-23 19:19:05 +05301564 device_name = (OMX_STRING)"/dev/video34";
Deepak Vermaa2efdb12013-12-26 12:30:05 +05301565 is_q6_platform = true;
1566 maxSmoothStreamingWidth = 1280;
1567 maxSmoothStreamingHeight = 720;
Arun Menon906de572013-06-18 17:01:40 -07001568 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001569#endif
1570
Arun Menon906de572013-06-18 17:01:40 -07001571 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1572 struct v4l2_control control;
1573 secure_mode = true;
1574 arbitrary_bytes = false;
1575 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301576 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
1577 OMX_MAX_STRINGNAME_SIZE)){
1578 secure_mode = true;
1579 arbitrary_bytes = false;
1580 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
Arun Menon906de572013-06-18 17:01:40 -07001581 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001582
Arun Menon906de572013-06-18 17:01:40 -07001583 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001584
Balamurugan Alagarsamy1693e592015-07-23 19:19:05 +05301585 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open device %s returned fd %d",
1586 device_name, drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001587
Arun Menon906de572013-06-18 17:01:40 -07001588 if (drv_ctx.video_driver_fd == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001589 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
Arun Menon906de572013-06-18 17:01:40 -07001590 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1591 close(0);
1592 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001593
Arun Menon906de572013-06-18 17:01:40 -07001594 if (drv_ctx.video_driver_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001595 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
Arun Menon906de572013-06-18 17:01:40 -07001596 return OMX_ErrorInsufficientResources;
1597 }
1598 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1599 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001600
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001601 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001602 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001603 async_thread_created = true;
1604 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1605 }
1606 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001607 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
Arun Menon906de572013-06-18 17:01:40 -07001608 async_thread_created = false;
1609 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001610 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001611
Shalaj Jain273b3e02012-06-22 19:08:03 -07001612#ifdef OUTPUT_EXTRADATA_LOG
Deva Ramasubramanianee6f1f42014-01-31 12:49:18 -08001613 outputExtradataFile = fopen (output_extradata_filename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001614#endif
1615
Arun Menon906de572013-06-18 17:01:40 -07001616 // Copy the role information which provides the decoder kind
1617 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001618
Arun Menon906de572013-06-18 17:01:40 -07001619 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1620 OMX_MAX_STRINGNAME_SIZE)) {
1621 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1622 OMX_MAX_STRINGNAME_SIZE);
1623 drv_ctx.timestamp_adjust = true;
1624 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1625 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1626 output_capability=V4L2_PIX_FMT_MPEG4;
1627 /*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;
1657 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001658
Arun Menon906de572013-06-18 17:01:40 -07001659 eRet = createDivxDrmContext();
1660 if (eRet != OMX_ErrorNone) {
1661 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1662 return eRet;
1663 }
1664 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1665 OMX_MAX_STRINGNAME_SIZE)) {
1666 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001667 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001668 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1669 output_capability = V4L2_PIX_FMT_DIVX;
1670 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1671 codec_type_parse = CODEC_TYPE_DIVX;
1672 codec_ambiguous = true;
1673 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001674
Arun Menon906de572013-06-18 17:01:40 -07001675 eRet = createDivxDrmContext();
1676 if (eRet != OMX_ErrorNone) {
1677 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1678 return eRet;
1679 }
1680 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1681 OMX_MAX_STRINGNAME_SIZE)) {
1682 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001683 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001684 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1685 output_capability = V4L2_PIX_FMT_DIVX;
1686 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1687 codec_type_parse = CODEC_TYPE_DIVX;
1688 codec_ambiguous = true;
1689 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001690
Arun Menon906de572013-06-18 17:01:40 -07001691 eRet = createDivxDrmContext();
1692 if (eRet != OMX_ErrorNone) {
1693 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1694 return eRet;
1695 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001696
Arun Menon906de572013-06-18 17:01:40 -07001697 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1698 OMX_MAX_STRINGNAME_SIZE)) {
1699 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1700 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1701 output_capability=V4L2_PIX_FMT_H264;
1702 eCompressionFormat = OMX_VIDEO_CodingAVC;
1703 codec_type_parse = CODEC_TYPE_H264;
1704 m_frame_parser.init_start_codes (codec_type_parse);
1705 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001706 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1707 OMX_MAX_STRINGNAME_SIZE)) {
1708 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1709 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1710 eCompressionFormat = OMX_VIDEO_CodingWMV;
1711 codec_type_parse = CODEC_TYPE_VC1;
1712 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1713 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001714 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1715 OMX_MAX_STRINGNAME_SIZE)) {
1716 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1717 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1718 eCompressionFormat = OMX_VIDEO_CodingWMV;
1719 codec_type_parse = CODEC_TYPE_VC1;
1720 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1721 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001722 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1723 OMX_MAX_STRINGNAME_SIZE)) {
1724 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1725 output_capability=V4L2_PIX_FMT_VP8;
Praveen Chavan76b71c32014-07-10 18:10:51 -07001726 eCompressionFormat = OMX_VIDEO_CodingVP8;
Arun Menon906de572013-06-18 17:01:40 -07001727 codec_type_parse = CODEC_TYPE_VP8;
1728 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001729
Arun Menon906de572013-06-18 17:01:40 -07001730 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001731 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07001732 eRet = OMX_ErrorInvalidComponentName;
1733 }
Arun Menon906de572013-06-18 17:01:40 -07001734 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001735
Arun Menon906de572013-06-18 17:01:40 -07001736 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001737 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1738 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1739 if (!client_buffers.set_color_format(dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001740 DEBUG_PRINT_ERROR("Setting color format failed");
Vinay Kaliada4f4422013-01-09 10:45:03 -08001741 eRet = OMX_ErrorInsufficientResources;
1742 }
1743
Arun Menon906de572013-06-18 17:01:40 -07001744 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001745
Arun Menon906de572013-06-18 17:01:40 -07001746 struct v4l2_capability cap;
1747 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1748 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001749 DEBUG_PRINT_ERROR("Failed to query capabilities");
Arun Menon906de572013-06-18 17:01:40 -07001750 /*TODO: How to handle this case */
1751 } else {
1752 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001753 " version = %d, capabilities = %x", cap.driver, cap.card,
Arun Menon906de572013-06-18 17:01:40 -07001754 cap.bus_info, cap.version, cap.capabilities);
1755 }
1756 ret=0;
1757 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1758 fdesc.index=0;
1759 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001760 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001761 fdesc.pixelformat, fdesc.flags);
1762 fdesc.index++;
1763 }
1764 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1765 fdesc.index=0;
1766 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001767
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001768 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001769 fdesc.pixelformat, fdesc.flags);
1770 fdesc.index++;
1771 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001772 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001773 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1774 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1775 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1776 fmt.fmt.pix_mp.pixelformat = output_capability;
1777 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1778 if (ret) {
1779 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001780 DEBUG_PRINT_ERROR("Failed to set format on output port");
Arun Menon906de572013-06-18 17:01:40 -07001781 return OMX_ErrorInsufficientResources;
1782 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001783 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001784 if (codec_ambiguous) {
1785 if (output_capability == V4L2_PIX_FMT_DIVX) {
1786 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001787
Arun Menon906de572013-06-18 17:01:40 -07001788 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1789 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1790 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1791 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1792 } else {
1793 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1794 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001795
Arun Menon906de572013-06-18 17:01:40 -07001796 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1797 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1798 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001799 DEBUG_PRINT_ERROR("Failed to set divx version");
Arun Menon906de572013-06-18 17:01:40 -07001800 }
1801 } else {
1802 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1803 }
1804 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001805
Jia Meng3a3c6492013-12-19 17:16:52 +08001806 property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
1807 m_conceal_color= atoi(property_value);
1808 DEBUG_PRINT_HIGH("trying to set 0x%x as conceal color\n",m_conceal_color);
1809 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
1810 control.value = m_conceal_color;
1811 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1812 if (ret) {
1813 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
1814 }
1815
Arun Menon906de572013-06-18 17:01:40 -07001816 //Get the hardware capabilities
1817 memset((void *)&frmsize,0,sizeof(frmsize));
1818 frmsize.index = 0;
1819 frmsize.pixel_format = output_capability;
1820 ret = ioctl(drv_ctx.video_driver_fd,
1821 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1822 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001823 DEBUG_PRINT_ERROR("Failed to get framesizes");
Arun Menon906de572013-06-18 17:01:40 -07001824 return OMX_ErrorHardware;
1825 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001826
Arun Menon906de572013-06-18 17:01:40 -07001827 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1828 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1829 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1830 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1831 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1832 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001833
Arun Menon906de572013-06-18 17:01:40 -07001834 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1835 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1836 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1837 fmt.fmt.pix_mp.pixelformat = capture_capability;
1838 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1839 if (ret) {
1840 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001841 DEBUG_PRINT_ERROR("Failed to set format on capture port");
Arun Menon906de572013-06-18 17:01:40 -07001842 }
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05301843 memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
1844 framesize.nWidth = drv_ctx.video_resolution.frame_width;
1845 framesize.nHeight = drv_ctx.video_resolution.frame_height;
1846
1847 memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
1848 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1849 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
1850
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001851 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001852 if (secure_mode) {
1853 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1854 control.value = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001855 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001856 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1857 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001858 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001859 return OMX_ErrorInsufficientResources;
1860 }
1861 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001862
Arun Menon906de572013-06-18 17:01:40 -07001863 /*Get the Buffer requirements for input and output ports*/
1864 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1865 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1866 if (secure_mode) {
1867 drv_ctx.op_buf.alignment=SZ_1M;
1868 drv_ctx.ip_buf.alignment=SZ_1M;
1869 } else {
1870 drv_ctx.op_buf.alignment=SZ_4K;
1871 drv_ctx.ip_buf.alignment=SZ_4K;
1872 }
1873 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1874 drv_ctx.extradata = 0;
1875 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1876 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1877 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1878 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1879 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001880
Vinay Kalia5713bb32013-01-16 18:39:59 -08001881 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001882#ifdef DEFAULT_EXTRADATA
Arun Menonf8908a62013-12-20 17:36:21 -08001883 if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
1884 OMX_MAX_STRINGNAME_SIZE) && (eRet == OMX_ErrorNone))
1885 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001886#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001887 eRet=get_buffer_req(&drv_ctx.ip_buf);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001888 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
Vinay Kalia5713bb32013-01-16 18:39:59 -08001889 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001890 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1891 if (m_frame_parser.mutils == NULL) {
1892 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001893
Arun Menon906de572013-06-18 17:01:40 -07001894 if (m_frame_parser.mutils == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001895 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001896 eRet = OMX_ErrorInsufficientResources;
1897 } else {
1898 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1899 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1900 h264_scratch.nFilledLen = 0;
1901 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001902
Arun Menon906de572013-06-18 17:01:40 -07001903 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001904 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001905 return OMX_ErrorInsufficientResources;
1906 }
1907 m_frame_parser.mutils->initialize_frame_checking_environment();
1908 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1909 }
1910 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001911
Arun Menon906de572013-06-18 17:01:40 -07001912 h264_parser = new h264_stream_parser();
1913 if (!h264_parser) {
1914 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1915 eRet = OMX_ErrorInsufficientResources;
1916 }
1917 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001918
Arun Menon906de572013-06-18 17:01:40 -07001919 if (pipe(fds)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001920 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001921 eRet = OMX_ErrorInsufficientResources;
1922 } else {
1923 int temp1[2];
1924 if (fds[0] == 0 || fds[1] == 0) {
1925 if (pipe (temp1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001926 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001927 return OMX_ErrorInsufficientResources;
1928 }
1929 //close (fds[0]);
1930 //close (fds[1]);
1931 fds[0] = temp1 [0];
1932 fds[1] = temp1 [1];
1933 }
1934 m_pipe_in = fds[0];
1935 m_pipe_out = fds[1];
1936 msg_thread_created = true;
Ashray Kulkarnia97efbc2015-07-15 18:17:23 -07001937 r = pthread_create(&msg_thread_id,0, dec_message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001938
Arun Menon906de572013-06-18 17:01:40 -07001939 if (r < 0) {
Ashray Kulkarnia97efbc2015-07-15 18:17:23 -07001940 DEBUG_PRINT_ERROR("component_init(): dec_message_thread creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001941 msg_thread_created = false;
1942 eRet = OMX_ErrorInsufficientResources;
1943 }
1944 }
1945 }
1946
1947 if (eRet != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001948 DEBUG_PRINT_ERROR("Component Init Failed");
Arun Menon906de572013-06-18 17:01:40 -07001949 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001950 DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
Arun Menon906de572013-06-18 17:01:40 -07001951 }
1952 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
Praveen Chavan898df262015-04-20 18:52:19 -07001953 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
1954 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
1955
1956 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
1957 DEBUG_PRINT_ERROR("Failed to set Default Priority");
1958 eRet = OMX_ErrorUnsupportedSetting;
1959 }
Arun Menon906de572013-06-18 17:01:40 -07001960 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001961}
1962
1963/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001964 FUNCTION
1965 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001966
Arun Menon906de572013-06-18 17:01:40 -07001967 DESCRIPTION
1968 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001969
Arun Menon906de572013-06-18 17:01:40 -07001970 PARAMETERS
1971 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001972
Arun Menon906de572013-06-18 17:01:40 -07001973 RETURN VALUE
1974 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001975
Arun Menon906de572013-06-18 17:01:40 -07001976 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001977OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001978(
1979 OMX_IN OMX_HANDLETYPE hComp,
1980 OMX_OUT OMX_STRING componentName,
1981 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1982 OMX_OUT OMX_VERSIONTYPE* specVersion,
1983 OMX_OUT OMX_UUIDTYPE* componentUUID
1984 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001985{
Arun Menon906de572013-06-18 17:01:40 -07001986 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001987 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001988 return OMX_ErrorInvalidState;
1989 }
Arun Menon906de572013-06-18 17:01:40 -07001990 /* TBD -- Return the proper version */
1991 if (specVersion) {
1992 specVersion->nVersion = OMX_SPEC_VERSION;
1993 }
1994 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001995}
1996/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001997 FUNCTION
1998 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001999
Arun Menon906de572013-06-18 17:01:40 -07002000 DESCRIPTION
2001 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07002002
Arun Menon906de572013-06-18 17:01:40 -07002003 PARAMETERS
2004 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002005
Arun Menon906de572013-06-18 17:01:40 -07002006 RETURN VALUE
2007 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002008
Arun Menon906de572013-06-18 17:01:40 -07002009 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002010OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002011 OMX_IN OMX_COMMANDTYPE cmd,
2012 OMX_IN OMX_U32 param1,
2013 OMX_IN OMX_PTR cmdData
2014 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002015{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002016 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07002017 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002018 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002019 return OMX_ErrorInvalidState;
2020 }
2021 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07002022 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002023 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07002024 "to invalid port: %lu", param1);
2025 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002026 }
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -07002027
Shalaj Jain273b3e02012-06-22 19:08:03 -07002028 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
2029 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002030 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002031 return OMX_ErrorNone;
2032}
2033
2034/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002035 FUNCTION
2036 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07002037
Arun Menon906de572013-06-18 17:01:40 -07002038 DESCRIPTION
2039 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07002040
Arun Menon906de572013-06-18 17:01:40 -07002041 PARAMETERS
2042 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002043
Arun Menon906de572013-06-18 17:01:40 -07002044 RETURN VALUE
2045 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002046
Arun Menon906de572013-06-18 17:01:40 -07002047 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002048OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002049 OMX_IN OMX_COMMANDTYPE cmd,
2050 OMX_IN OMX_U32 param1,
2051 OMX_IN OMX_PTR cmdData
2052 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002053{
Arun Menon906de572013-06-18 17:01:40 -07002054 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2055 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
2056 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002057
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002058 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
2059 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07002060 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002061
Arun Menon906de572013-06-18 17:01:40 -07002062 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002063 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
2064 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07002065 /***************************/
2066 /* Current State is Loaded */
2067 /***************************/
2068 if (m_state == OMX_StateLoaded) {
2069 if (eState == OMX_StateIdle) {
2070 //if all buffers are allocated or all ports disabled
2071 if (allocate_done() ||
2072 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002073 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002074 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002075 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002076 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
2077 // Skip the event notification
2078 bFlag = 0;
2079 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002080 }
Arun Menon906de572013-06-18 17:01:40 -07002081 /* Requesting transition from Loaded to Loaded */
2082 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002083 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002084 post_event(OMX_EventError,OMX_ErrorSameState,\
2085 OMX_COMPONENT_GENERATE_EVENT);
2086 eRet = OMX_ErrorSameState;
2087 }
2088 /* Requesting transition from Loaded to WaitForResources */
2089 else if (eState == OMX_StateWaitForResources) {
2090 /* Since error is None , we will post an event
2091 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002092 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002093 }
2094 /* Requesting transition from Loaded to Executing */
2095 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002096 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002097 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2098 OMX_COMPONENT_GENERATE_EVENT);
2099 eRet = OMX_ErrorIncorrectStateTransition;
2100 }
2101 /* Requesting transition from Loaded to Pause */
2102 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002103 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002104 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2105 OMX_COMPONENT_GENERATE_EVENT);
2106 eRet = OMX_ErrorIncorrectStateTransition;
2107 }
2108 /* Requesting transition from Loaded to Invalid */
2109 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002110 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002111 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2112 eRet = OMX_ErrorInvalidState;
2113 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002114 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07002115 eState);
2116 eRet = OMX_ErrorBadParameter;
2117 }
2118 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002119
Arun Menon906de572013-06-18 17:01:40 -07002120 /***************************/
2121 /* Current State is IDLE */
2122 /***************************/
2123 else if (m_state == OMX_StateIdle) {
2124 if (eState == OMX_StateLoaded) {
2125 if (release_done()) {
2126 /*
2127 Since error is None , we will post an event at the end
2128 of this function definition
2129 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002130 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002131 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002132 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07002133 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2134 // Skip the event notification
2135 bFlag = 0;
2136 }
2137 }
2138 /* Requesting transition from Idle to Executing */
2139 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002140 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002141 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2142 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002143 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002144 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002145 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07002146 }
2147 /* Requesting transition from Idle to Idle */
2148 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002149 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002150 post_event(OMX_EventError,OMX_ErrorSameState,\
2151 OMX_COMPONENT_GENERATE_EVENT);
2152 eRet = OMX_ErrorSameState;
2153 }
2154 /* Requesting transition from Idle to WaitForResources */
2155 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002156 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002157 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2158 OMX_COMPONENT_GENERATE_EVENT);
2159 eRet = OMX_ErrorIncorrectStateTransition;
2160 }
2161 /* Requesting transition from Idle to Pause */
2162 else if (eState == OMX_StatePause) {
2163 /*To pause the Video core we need to start the driver*/
2164 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2165 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002166 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002167 omx_report_error ();
2168 eRet = OMX_ErrorHardware;
2169 } else {
2170 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002171 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002172 bFlag = 0;
2173 }
2174 }
2175 /* Requesting transition from Idle to Invalid */
2176 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002177 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002178 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2179 eRet = OMX_ErrorInvalidState;
2180 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002181 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002182 eRet = OMX_ErrorBadParameter;
2183 }
2184 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002185
Arun Menon906de572013-06-18 17:01:40 -07002186 /******************************/
2187 /* Current State is Executing */
2188 /******************************/
2189 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002190 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002191 /* Requesting transition from Executing to Idle */
2192 if (eState == OMX_StateIdle) {
2193 /* Since error is None , we will post an event
2194 at the end of this function definition
2195 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002196 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002197 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2198 if (!sem_posted) {
2199 sem_posted = 1;
2200 sem_post (&m_cmd_lock);
2201 execute_omx_flush(OMX_ALL);
2202 }
2203 bFlag = 0;
2204 }
2205 /* Requesting transition from Executing to Paused */
2206 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002207 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002208 m_state = OMX_StatePause;
2209 bFlag = 1;
2210 }
2211 /* Requesting transition from Executing to Loaded */
2212 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002213 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002214 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2215 OMX_COMPONENT_GENERATE_EVENT);
2216 eRet = OMX_ErrorIncorrectStateTransition;
2217 }
2218 /* Requesting transition from Executing to WaitForResources */
2219 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002220 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002221 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2222 OMX_COMPONENT_GENERATE_EVENT);
2223 eRet = OMX_ErrorIncorrectStateTransition;
2224 }
2225 /* Requesting transition from Executing to Executing */
2226 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002227 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002228 post_event(OMX_EventError,OMX_ErrorSameState,\
2229 OMX_COMPONENT_GENERATE_EVENT);
2230 eRet = OMX_ErrorSameState;
2231 }
2232 /* Requesting transition from Executing to Invalid */
2233 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002234 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002235 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2236 eRet = OMX_ErrorInvalidState;
2237 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002238 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002239 eRet = OMX_ErrorBadParameter;
2240 }
2241 }
2242 /***************************/
2243 /* Current State is Pause */
2244 /***************************/
2245 else if (m_state == OMX_StatePause) {
2246 /* Requesting transition from Pause to Executing */
2247 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002248 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002249 m_state = OMX_StateExecuting;
2250 bFlag = 1;
2251 }
2252 /* Requesting transition from Pause to Idle */
2253 else if (eState == OMX_StateIdle) {
2254 /* Since error is None , we will post an event
2255 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002256 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002257 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2258 if (!sem_posted) {
2259 sem_posted = 1;
2260 sem_post (&m_cmd_lock);
2261 execute_omx_flush(OMX_ALL);
2262 }
2263 bFlag = 0;
2264 }
2265 /* Requesting transition from Pause to loaded */
2266 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002267 DEBUG_PRINT_ERROR("Pause --> loaded");
Arun Menon906de572013-06-18 17:01:40 -07002268 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2269 OMX_COMPONENT_GENERATE_EVENT);
2270 eRet = OMX_ErrorIncorrectStateTransition;
2271 }
2272 /* Requesting transition from Pause to WaitForResources */
2273 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002274 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002275 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2276 OMX_COMPONENT_GENERATE_EVENT);
2277 eRet = OMX_ErrorIncorrectStateTransition;
2278 }
2279 /* Requesting transition from Pause to Pause */
2280 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002281 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002282 post_event(OMX_EventError,OMX_ErrorSameState,\
2283 OMX_COMPONENT_GENERATE_EVENT);
2284 eRet = OMX_ErrorSameState;
2285 }
2286 /* Requesting transition from Pause to Invalid */
2287 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002288 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002289 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2290 eRet = OMX_ErrorInvalidState;
2291 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002292 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002293 eRet = OMX_ErrorBadParameter;
2294 }
2295 }
2296 /***************************/
2297 /* Current State is WaitForResources */
2298 /***************************/
2299 else if (m_state == OMX_StateWaitForResources) {
2300 /* Requesting transition from WaitForResources to Loaded */
2301 if (eState == OMX_StateLoaded) {
2302 /* Since error is None , we will post an event
2303 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002304 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002305 }
2306 /* Requesting transition from WaitForResources to WaitForResources */
2307 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002308 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002309 post_event(OMX_EventError,OMX_ErrorSameState,
2310 OMX_COMPONENT_GENERATE_EVENT);
2311 eRet = OMX_ErrorSameState;
2312 }
2313 /* Requesting transition from WaitForResources to Executing */
2314 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002315 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002316 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2317 OMX_COMPONENT_GENERATE_EVENT);
2318 eRet = OMX_ErrorIncorrectStateTransition;
2319 }
2320 /* Requesting transition from WaitForResources to Pause */
2321 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002322 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002323 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2324 OMX_COMPONENT_GENERATE_EVENT);
2325 eRet = OMX_ErrorIncorrectStateTransition;
2326 }
2327 /* Requesting transition from WaitForResources to Invalid */
2328 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002329 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002330 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2331 eRet = OMX_ErrorInvalidState;
2332 }
2333 /* Requesting transition from WaitForResources to Loaded -
2334 is NOT tested by Khronos TS */
2335
2336 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002337 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002338 eRet = OMX_ErrorBadParameter;
2339 }
2340 }
2341 /********************************/
2342 /* Current State is Invalid */
2343 /*******************************/
2344 else if (m_state == OMX_StateInvalid) {
2345 /* State Transition from Inavlid to any state */
2346 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2347 || OMX_StateIdle || OMX_StateExecuting
2348 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002349 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002350 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2351 OMX_COMPONENT_GENERATE_EVENT);
2352 eRet = OMX_ErrorInvalidState;
2353 }
2354 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002355 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002356 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002357#ifdef _MSM8974_
2358 send_codec_config();
2359#endif
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302360 if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
2361 param1 == OMX_ALL)) {
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05302362 if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302363 struct timespec ts;
2364
2365 clock_gettime(CLOCK_REALTIME, &ts);
2366 ts.tv_sec += 2;
2367 DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
2368 m_queued_codec_config_count);
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05302369 BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302370 if (sem_timedwait(&m_safe_flush, &ts)) {
2371 DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302372 }
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05302373 BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
Srinu Gorleaf1b9fb2014-08-29 19:40:27 +05302374 }
2375 }
2376
Arun Menon906de572013-06-18 17:01:40 -07002377 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2378 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2379 }
2380 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2381 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2382 }
2383 if (!sem_posted) {
2384 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002385 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002386 sem_post (&m_cmd_lock);
2387 execute_omx_flush(param1);
2388 }
2389 bFlag = 0;
2390 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002391 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002392 "with param1: %lu", param1);
2393 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2394 m_inp_bEnabled = OMX_TRUE;
2395
2396 if ( (m_state == OMX_StateLoaded &&
2397 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2398 || allocate_input_done()) {
2399 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2400 OMX_COMPONENT_GENERATE_EVENT);
2401 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002402 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002403 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2404 // Skip the event notification
2405 bFlag = 0;
2406 }
2407 }
2408 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002409 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002410 m_out_bEnabled = OMX_TRUE;
2411
2412 if ( (m_state == OMX_StateLoaded &&
2413 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2414 || (allocate_output_done())) {
2415 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2416 OMX_COMPONENT_GENERATE_EVENT);
2417
2418 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002419 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002420 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2421 // Skip the event notification
2422 bFlag = 0;
2423 }
2424 }
2425 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002426 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002427 "with param1: %lu", param1);
2428 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002429 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002430 m_inp_bEnabled = OMX_FALSE;
2431 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2432 && release_input_done()) {
2433 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2434 OMX_COMPONENT_GENERATE_EVENT);
2435 } else {
2436 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2437 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2438 if (!sem_posted) {
2439 sem_posted = 1;
2440 sem_post (&m_cmd_lock);
2441 }
2442 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2443 }
2444
2445 // Skip the event notification
2446 bFlag = 0;
2447 }
2448 }
2449 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2450 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002451 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002452 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2453 && release_output_done()) {
2454 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2455 OMX_COMPONENT_GENERATE_EVENT);
2456 } else {
2457 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2458 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2459 if (!sem_posted) {
2460 sem_posted = 1;
2461 sem_post (&m_cmd_lock);
2462 }
2463 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2464 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2465 }
2466 // Skip the event notification
2467 bFlag = 0;
2468
2469 }
2470 }
2471 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002472 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002473 eRet = OMX_ErrorNotImplemented;
2474 }
2475 if (eRet == OMX_ErrorNone && bFlag) {
2476 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2477 }
2478 if (!sem_posted) {
2479 sem_post(&m_cmd_lock);
2480 }
2481
2482 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002483}
2484
2485/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002486 FUNCTION
2487 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002488
Arun Menon906de572013-06-18 17:01:40 -07002489 DESCRIPTION
2490 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002491
Arun Menon906de572013-06-18 17:01:40 -07002492 PARAMETERS
2493 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002494
Arun Menon906de572013-06-18 17:01:40 -07002495 RETURN VALUE
2496 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002497
Arun Menon906de572013-06-18 17:01:40 -07002498 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002499bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2500{
Arun Menon906de572013-06-18 17:01:40 -07002501 bool bRet = false;
2502 struct v4l2_plane plane;
2503 struct v4l2_buffer v4l2_buf;
2504 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302505 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002506 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2507 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002508
Arun Menon906de572013-06-18 17:01:40 -07002509 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002510
Arun Menon906de572013-06-18 17:01:40 -07002511 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2512 output_flush_progress = true;
2513 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2514 } else {
2515 /* XXX: The driver/hardware does not support flushing of individual ports
2516 * in all states. So we pretty much need to flush both ports internally,
2517 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2518 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2519 * we automatically omit sending the FLUSH done for the "opposite" port. */
2520 input_flush_progress = true;
2521 output_flush_progress = true;
2522 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2523 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002524
Arun Menon906de572013-06-18 17:01:40 -07002525 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002526 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002527 bRet = false;
2528 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002529
Arun Menon906de572013-06-18 17:01:40 -07002530 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002531}
2532/*=========================================================================
2533FUNCTION : execute_output_flush
2534
2535DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002536Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002537
2538PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002539None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002540
2541RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002542true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002543==========================================================================*/
2544bool omx_vdec::execute_output_flush()
2545{
Arun Menon906de572013-06-18 17:01:40 -07002546 unsigned p1 = 0; // Parameter - 1
2547 unsigned p2 = 0; // Parameter - 2
2548 unsigned ident = 0;
2549 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002550
Arun Menon906de572013-06-18 17:01:40 -07002551 /*Generate FBD for all Buffers in the FTBq*/
2552 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002553 DEBUG_PRINT_LOW("Initiate Output Flush");
vivek mehta79cff222014-01-22 12:17:07 -08002554
2555 //reset last render TS
2556 if(m_last_rendered_TS > 0) {
2557 m_last_rendered_TS = 0;
2558 }
vivek mehtaa75c69f2014-01-10 21:50:37 -08002559
Arun Menon906de572013-06-18 17:01:40 -07002560 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002561 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002562 m_ftb_q.m_size,pending_output_buffers);
2563 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002564 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002565 if (ident == m_fill_output_msg ) {
2566 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2567 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2568 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2569 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002570 }
Arun Menon906de572013-06-18 17:01:40 -07002571 pthread_mutex_unlock(&m_lock);
2572 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002573
Arun Menon906de572013-06-18 17:01:40 -07002574 if (arbitrary_bytes) {
2575 prev_ts = LLONG_MAX;
2576 rst_prev_ts = true;
2577 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002578 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002579 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002580}
2581/*=========================================================================
2582FUNCTION : execute_input_flush
2583
2584DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002585Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002586
2587PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002588None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002589
2590RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002591true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002592==========================================================================*/
2593bool omx_vdec::execute_input_flush()
2594{
Arun Menon906de572013-06-18 17:01:40 -07002595 unsigned i =0;
2596 unsigned p1 = 0; // Parameter - 1
2597 unsigned p2 = 0; // Parameter - 2
2598 unsigned ident = 0;
2599 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002600
Arun Menon906de572013-06-18 17:01:40 -07002601 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002602 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002603
Arun Menon906de572013-06-18 17:01:40 -07002604 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002605 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002606 while (m_etb_q.m_size) {
2607 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002608
Arun Menon906de572013-06-18 17:01:40 -07002609 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002610 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002611 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2612 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2613 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002614 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002615 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2616 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2617 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002618 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002619 (OMX_BUFFERHEADERTYPE *)p1);
2620 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2621 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002622 }
Arun Menon906de572013-06-18 17:01:40 -07002623 time_stamp_dts.flush_timestamp();
2624 /*Check if Heap Buffers are to be flushed*/
2625 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002626 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002627 h264_scratch.nFilledLen = 0;
2628 nal_count = 0;
2629 look_ahead_nal = false;
2630 frame_count = 0;
2631 h264_last_au_ts = LLONG_MAX;
2632 h264_last_au_flags = 0;
2633 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2634 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002635 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002636 if (m_frame_parser.mutils) {
2637 m_frame_parser.mutils->initialize_frame_checking_environment();
2638 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002639
Arun Menon906de572013-06-18 17:01:40 -07002640 while (m_input_pending_q.m_size) {
2641 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2642 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2643 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002644
Arun Menon906de572013-06-18 17:01:40 -07002645 if (psource_frame) {
2646 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2647 psource_frame = NULL;
2648 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002649
Arun Menon906de572013-06-18 17:01:40 -07002650 if (pdest_frame) {
2651 pdest_frame->nFilledLen = 0;
2652 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2653 (unsigned int)NULL);
2654 pdest_frame = NULL;
2655 }
2656 m_frame_parser.flush();
2657 } else if (codec_config_flag) {
2658 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2659 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002660 }
Arun Menon906de572013-06-18 17:01:40 -07002661 pthread_mutex_unlock(&m_lock);
2662 input_flush_progress = false;
2663 if (!arbitrary_bytes) {
2664 prev_ts = LLONG_MAX;
2665 rst_prev_ts = true;
2666 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002667#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002668 if (m_debug_timestamp) {
2669 m_timestamp_list.reset_ts_list();
2670 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002671#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002672 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002673 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002674}
2675
2676
2677/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002678 FUNCTION
2679 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002680
Arun Menon906de572013-06-18 17:01:40 -07002681 DESCRIPTION
2682 Send the event to decoder pipe. This is needed to generate the callbacks
2683 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002684
Arun Menon906de572013-06-18 17:01:40 -07002685 PARAMETERS
2686 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002687
Arun Menon906de572013-06-18 17:01:40 -07002688 RETURN VALUE
2689 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002690
Arun Menon906de572013-06-18 17:01:40 -07002691 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002692bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002693 unsigned int p2,
2694 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002695{
Arun Menon906de572013-06-18 17:01:40 -07002696 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002697
2698
Arun Menon906de572013-06-18 17:01:40 -07002699 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002700
Arun Menon906de572013-06-18 17:01:40 -07002701 if (id == m_fill_output_msg ||
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05302702 id == OMX_COMPONENT_GENERATE_FBD ||
2703 id == OMX_COMPONENT_GENERATE_PORT_RECONFIG) {
Arun Menon906de572013-06-18 17:01:40 -07002704 m_ftb_q.insert_entry(p1,p2,id);
2705 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2706 id == OMX_COMPONENT_GENERATE_EBD ||
2707 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2708 m_etb_q.insert_entry(p1,p2,id);
2709 } else {
2710 m_cmd_q.insert_entry(p1,p2,id);
2711 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002712
Arun Menon906de572013-06-18 17:01:40 -07002713 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002714 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002715 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002716
Arun Menon906de572013-06-18 17:01:40 -07002717 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002718
Arun Menon906de572013-06-18 17:01:40 -07002719 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002720}
2721
2722OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2723{
Arun Menon906de572013-06-18 17:01:40 -07002724 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2725 if (!profileLevelType)
2726 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002727
Arun Menon906de572013-06-18 17:01:40 -07002728 if (profileLevelType->nPortIndex == 0) {
2729 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2730 if (profileLevelType->nProfileIndex == 0) {
2731 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2732 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002733
Arun Menon906de572013-06-18 17:01:40 -07002734 } else if (profileLevelType->nProfileIndex == 1) {
2735 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2736 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2737 } else if (profileLevelType->nProfileIndex == 2) {
2738 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2739 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2740 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002741 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002742 profileLevelType->nProfileIndex);
2743 eRet = OMX_ErrorNoMore;
2744 }
2745 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2746 if (profileLevelType->nProfileIndex == 0) {
2747 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2748 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2749 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002750 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002751 eRet = OMX_ErrorNoMore;
2752 }
2753 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2754 if (profileLevelType->nProfileIndex == 0) {
2755 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2756 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2757 } else if (profileLevelType->nProfileIndex == 1) {
2758 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2759 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2760 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002761 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002762 eRet = OMX_ErrorNoMore;
2763 }
2764 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2765 eRet = OMX_ErrorNoMore;
2766 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2767 if (profileLevelType->nProfileIndex == 0) {
2768 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2769 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2770 } else if (profileLevelType->nProfileIndex == 1) {
2771 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2772 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2773 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002774 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002775 eRet = OMX_ErrorNoMore;
2776 }
2777 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002778 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002779 eRet = OMX_ErrorNoMore;
2780 }
2781 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002782 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002783 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002784 }
Arun Menon906de572013-06-18 17:01:40 -07002785 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002786}
2787
2788/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002789 FUNCTION
2790 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002791
Arun Menon906de572013-06-18 17:01:40 -07002792 DESCRIPTION
2793 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002794
Arun Menon906de572013-06-18 17:01:40 -07002795 PARAMETERS
2796 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002797
Arun Menon906de572013-06-18 17:01:40 -07002798 RETURN VALUE
2799 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002800
Arun Menon906de572013-06-18 17:01:40 -07002801 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002802OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002803 OMX_IN OMX_INDEXTYPE paramIndex,
2804 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002805{
2806 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2807
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002808 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002809 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002810 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002811 return OMX_ErrorInvalidState;
2812 }
Arun Menon906de572013-06-18 17:01:40 -07002813 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002814 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002815 return OMX_ErrorBadParameter;
2816 }
Arun Menon906de572013-06-18 17:01:40 -07002817 switch ((unsigned long)paramIndex) {
2818 case OMX_IndexParamPortDefinition: {
2819 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2820 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002821 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002822 eRet = update_portdef(portDefn);
2823 if (eRet == OMX_ErrorNone)
2824 m_port_def = *portDefn;
2825 break;
2826 }
2827 case OMX_IndexParamVideoInit: {
2828 OMX_PORT_PARAM_TYPE *portParamType =
2829 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002830 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002831
Arun Menon906de572013-06-18 17:01:40 -07002832 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2833 portParamType->nSize = sizeof(portParamType);
2834 portParamType->nPorts = 2;
2835 portParamType->nStartPortNumber = 0;
2836 break;
2837 }
2838 case OMX_IndexParamVideoPortFormat: {
2839 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2840 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002841 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002842
Arun Menon906de572013-06-18 17:01:40 -07002843 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2844 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002845
Arun Menon906de572013-06-18 17:01:40 -07002846 if (0 == portFmt->nPortIndex) {
2847 if (0 == portFmt->nIndex) {
2848 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2849 portFmt->eCompressionFormat = eCompressionFormat;
2850 } else {
2851 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002852 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002853 eRet = OMX_ErrorNoMore;
2854 }
2855 } else if (1 == portFmt->nPortIndex) {
2856 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002857
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07002858 // Distinguish non-surface mode from normal playback use-case based on
2859 // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
2860 // For non-android, use the default list
Praveen Chavancac86402014-10-18 09:14:52 -07002861 // Also use default format-list if FLEXIBLE YUV is supported,
2862 // as the client negotiates the standard color-format if it needs to
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07002863 bool useNonSurfaceMode = false;
Praveen Chavancac86402014-10-18 09:14:52 -07002864#if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED)
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07002865 useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
2866#endif
2867 portFmt->eColorFormat = useNonSurfaceMode ?
2868 getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
2869 getPreferredColorFormatDefaultMode(portFmt->nIndex);
2870
2871 if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
Praveen Chavandb7776f2014-02-06 18:17:25 -08002872 eRet = OMX_ErrorNoMore;
Arun Menon906de572013-06-18 17:01:40 -07002873 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002874 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002875 }
Praveen Chavandb7776f2014-02-06 18:17:25 -08002876 DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002877 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002878 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002879 (int)portFmt->nPortIndex);
2880 eRet = OMX_ErrorBadPortIndex;
2881 }
2882 break;
2883 }
2884 /*Component should support this port definition*/
2885 case OMX_IndexParamAudioInit: {
2886 OMX_PORT_PARAM_TYPE *audioPortParamType =
2887 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002888 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002889 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2890 audioPortParamType->nSize = sizeof(audioPortParamType);
2891 audioPortParamType->nPorts = 0;
2892 audioPortParamType->nStartPortNumber = 0;
2893 break;
2894 }
2895 /*Component should support this port definition*/
2896 case OMX_IndexParamImageInit: {
2897 OMX_PORT_PARAM_TYPE *imagePortParamType =
2898 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002899 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002900 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2901 imagePortParamType->nSize = sizeof(imagePortParamType);
2902 imagePortParamType->nPorts = 0;
2903 imagePortParamType->nStartPortNumber = 0;
2904 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002905
Arun Menon906de572013-06-18 17:01:40 -07002906 }
2907 /*Component should support this port definition*/
2908 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002909 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002910 paramIndex);
2911 eRet =OMX_ErrorUnsupportedIndex;
2912 break;
2913 }
2914 case OMX_IndexParamStandardComponentRole: {
2915 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2916 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2917 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2918 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002919
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002920 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002921 paramIndex);
2922 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2923 OMX_MAX_STRINGNAME_SIZE);
2924 break;
2925 }
2926 /* Added for parameter test */
2927 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002928
Arun Menon906de572013-06-18 17:01:40 -07002929 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2930 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002931 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002932 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2933 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002934
Arun Menon906de572013-06-18 17:01:40 -07002935 break;
2936 }
2937 /* Added for parameter test */
2938 case OMX_IndexParamCompBufferSupplier: {
2939 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2940 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002941 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002942
Arun Menon906de572013-06-18 17:01:40 -07002943 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2944 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2945 if (0 == bufferSupplierType->nPortIndex)
2946 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2947 else if (1 == bufferSupplierType->nPortIndex)
2948 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2949 else
2950 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002951
2952
Arun Menon906de572013-06-18 17:01:40 -07002953 break;
2954 }
2955 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002956 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002957 paramIndex);
2958 break;
2959 }
2960 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002961 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002962 paramIndex);
2963 break;
2964 }
2965 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002966 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002967 paramIndex);
2968 break;
2969 }
2970 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002971 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002972 paramIndex);
2973 break;
2974 }
2975 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002976 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002977 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2978 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2979 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2980 break;
2981 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002982#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002983 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002984 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002985 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2986 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002987
Arun Menon906de572013-06-18 17:01:40 -07002988 if (secure_mode) {
2989 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2990 GRALLOC_USAGE_PRIVATE_UNCACHED);
2991 } else {
2992 nativeBuffersUsage->nUsage =
2993 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2994 GRALLOC_USAGE_PRIVATE_UNCACHED);
2995 }
2996 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002997 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002998 eRet = OMX_ErrorBadParameter;
2999 }
3000 }
3001 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003002#endif
3003
Praveen Chavan09a82b72014-10-18 09:09:45 -07003004#ifdef FLEXYUV_SUPPORTED
3005 case OMX_QcomIndexFlexibleYUVDescription: {
3006 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
3007 eRet = describeColorFormat(paramData);
3008 break;
3009 }
3010#endif
3011
Arun Menon906de572013-06-18 17:01:40 -07003012 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003013 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003014 eRet =OMX_ErrorUnsupportedIndex;
3015 }
3016
Shalaj Jain273b3e02012-06-22 19:08:03 -07003017 }
3018
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003019 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07003020 drv_ctx.video_resolution.frame_width,
3021 drv_ctx.video_resolution.frame_height,
3022 drv_ctx.video_resolution.stride,
3023 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003024
Arun Menon906de572013-06-18 17:01:40 -07003025 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003026}
3027
3028#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3029OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
3030{
3031 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
3032 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3033 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
3034
Arun Menon906de572013-06-18 17:01:40 -07003035 if ((params == NULL) ||
3036 (params->nativeBuffer == NULL) ||
3037 (params->nativeBuffer->handle == NULL) ||
3038 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003039 return OMX_ErrorBadParameter;
3040 m_use_android_native_buffers = OMX_TRUE;
3041 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3042 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07003043 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 -07003044 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07003045 if (!secure_mode) {
3046 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003047 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07003048 if (buffer == MAP_FAILED) {
3049 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3050 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003051 }
3052 }
3053 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3054 } else {
3055 eRet = OMX_ErrorBadParameter;
3056 }
3057 return eRet;
3058}
3059#endif
Praveen Chavancf924182013-12-06 23:16:23 -08003060
3061OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
3062 struct v4l2_control control;
3063 struct v4l2_format fmt;
3064 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3065 control.value = 1;
3066 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3067 if (rc < 0) {
3068 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3069 return OMX_ErrorHardware;
3070 }
3071 m_smoothstreaming_mode = true;
3072 return OMX_ErrorNone;
3073}
3074
Shalaj Jain273b3e02012-06-22 19:08:03 -07003075/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003076 FUNCTION
3077 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07003078
Arun Menon906de572013-06-18 17:01:40 -07003079 DESCRIPTION
3080 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003081
Arun Menon906de572013-06-18 17:01:40 -07003082 PARAMETERS
3083 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003084
Arun Menon906de572013-06-18 17:01:40 -07003085 RETURN VALUE
3086 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003087
Arun Menon906de572013-06-18 17:01:40 -07003088 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003089OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003090 OMX_IN OMX_INDEXTYPE paramIndex,
3091 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003092{
3093 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003094 int ret=0;
3095 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07003096 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003097 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003098 return OMX_ErrorInvalidState;
3099 }
Arun Menon906de572013-06-18 17:01:40 -07003100 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003101 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07003102 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003103 }
Arun Menon906de572013-06-18 17:01:40 -07003104 if ((m_state != OMX_StateLoaded) &&
3105 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3106 (m_out_bEnabled == OMX_TRUE) &&
3107 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3108 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003109 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003110 return OMX_ErrorIncorrectStateOperation;
3111 }
Arun Menon906de572013-06-18 17:01:40 -07003112 switch ((unsigned long)paramIndex) {
3113 case OMX_IndexParamPortDefinition: {
3114 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3115 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3116 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3117 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003118 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07003119 (int)portDefn->format.video.nFrameHeight,
3120 (int)portDefn->format.video.nFrameWidth);
3121 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003122 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Pushkaraj Patil41588352014-02-25 20:51:34 +05303123 bool port_format_changed = false;
Arun Menon906de572013-06-18 17:01:40 -07003124 m_display_id = portDefn->format.video.pNativeWindow;
3125 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08003126 /* update output port resolution with client supplied dimensions
3127 in case scaling is enabled, else it follows input resolution set
3128 */
3129 if (is_down_scalar_enabled) {
3130 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003131 portDefn->format.video.nFrameWidth,
3132 portDefn->format.video.nFrameHeight);
3133 if (portDefn->format.video.nFrameHeight != 0x0 &&
3134 portDefn->format.video.nFrameWidth != 0x0) {
Pushkaraj Patil41588352014-02-25 20:51:34 +05303135 memset(&fmt, 0x0, sizeof(struct v4l2_format));
3136 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3137 fmt.fmt.pix_mp.pixelformat = capture_capability;
3138 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
3139 if (ret) {
3140 DEBUG_PRINT_ERROR("Get Resolution failed");
3141 eRet = OMX_ErrorHardware;
3142 break;
3143 }
3144 if ((portDefn->format.video.nFrameHeight != (int)fmt.fmt.pix_mp.height) ||
3145 (portDefn->format.video.nFrameWidth != (int)fmt.fmt.pix_mp.width)) {
3146 port_format_changed = true;
3147 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003148 update_resolution(portDefn->format.video.nFrameWidth,
3149 portDefn->format.video.nFrameHeight,
3150 portDefn->format.video.nFrameWidth,
3151 portDefn->format.video.nFrameHeight);
Pushkaraj Patil41588352014-02-25 20:51:34 +05303152
3153 /* set crop info */
3154 rectangle.nLeft = 0;
3155 rectangle.nTop = 0;
3156 rectangle.nWidth = portDefn->format.video.nFrameWidth;
3157 rectangle.nHeight = portDefn->format.video.nFrameHeight;
3158
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003159 eRet = is_video_session_supported();
3160 if (eRet)
3161 break;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303162 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003163 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3164 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3165 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3166 fmt.fmt.pix_mp.pixelformat = capture_capability;
3167 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);
3168 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3169 if (ret) {
3170 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3171 eRet = OMX_ErrorUnsupportedSetting;
3172 } else
3173 eRet = get_buffer_req(&drv_ctx.op_buf);
3174 }
Praveen Chavane78460c2013-12-06 23:16:04 -08003175 }
Arun Menon906de572013-06-18 17:01:40 -07003176 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003177 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07003178 eRet = OMX_ErrorBadParameter;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303179 } else if (!port_format_changed) {
Arun Menon906de572013-06-18 17:01:40 -07003180 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3181 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
3182 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3183 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3184 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
3185 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
3186 drv_ctx.extradata_info.buffer_size;
3187 eRet = set_buffer_req(&drv_ctx.op_buf);
3188 if (eRet == OMX_ErrorNone)
3189 m_port_def = *portDefn;
3190 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003191 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003192 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3193 portDefn->nBufferCountActual, portDefn->nBufferSize);
3194 eRet = OMX_ErrorBadParameter;
3195 }
3196 }
3197 } else if (OMX_DirInput == portDefn->eDir) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003198 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003199 bool port_format_changed = false;
3200 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
3201 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
3202 // Frame rate only should be set if this is a "known value" or to
3203 // activate ts prediction logic (arbitrary mode only) sending input
3204 // timestamps with max value (LLONG_MAX).
3205 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
3206 portDefn->format.video.xFramerate >> 16);
3207 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3208 drv_ctx.frame_rate.fps_denominator);
3209 if (!drv_ctx.frame_rate.fps_numerator) {
3210 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3211 drv_ctx.frame_rate.fps_numerator = 30;
3212 }
3213 if (drv_ctx.frame_rate.fps_denominator)
3214 drv_ctx.frame_rate.fps_numerator = (int)
3215 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3216 drv_ctx.frame_rate.fps_denominator = 1;
3217 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3218 drv_ctx.frame_rate.fps_numerator;
3219 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3220 frm_int, drv_ctx.frame_rate.fps_numerator /
3221 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003222
3223 struct v4l2_outputparm oparm;
3224 /*XXX: we're providing timing info as seconds per frame rather than frames
3225 * per second.*/
3226 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3227 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3228
3229 struct v4l2_streamparm sparm;
3230 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3231 sparm.parm.output = oparm;
3232 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3233 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
3234 eRet = OMX_ErrorHardware;
3235 break;
3236 }
Arun Menon906de572013-06-18 17:01:40 -07003237 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08003238
Arun Menon906de572013-06-18 17:01:40 -07003239 if (drv_ctx.video_resolution.frame_height !=
3240 portDefn->format.video.nFrameHeight ||
3241 drv_ctx.video_resolution.frame_width !=
3242 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003243 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003244 portDefn->format.video.nFrameWidth,
3245 portDefn->format.video.nFrameHeight);
3246 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003247 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3248 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3249 if (frameHeight != 0x0 && frameWidth != 0x0) {
3250 if (m_smoothstreaming_mode &&
3251 ((frameWidth * frameHeight) <
3252 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3253 frameWidth = m_smoothstreaming_width;
3254 frameHeight = m_smoothstreaming_height;
3255 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3256 frameWidth, frameHeight);
3257 }
3258 update_resolution(frameWidth, frameHeight,
3259 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003260 eRet = is_video_session_supported();
3261 if (eRet)
3262 break;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303263 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Arun Menon906de572013-06-18 17:01:40 -07003264 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3265 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3266 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3267 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003268 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 -07003269 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3270 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003271 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003272 eRet = OMX_ErrorUnsupportedSetting;
Pushkaraj Patil41588352014-02-25 20:51:34 +05303273 } else {
3274 if (!is_down_scalar_enabled)
3275 eRet = get_buffer_req(&drv_ctx.op_buf);
3276 }
Arun Menon906de572013-06-18 17:01:40 -07003277 }
3278 }
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +05303279 if (m_custom_buffersize.input_buffersize
3280 && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
3281 DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
3282 m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
3283 eRet = OMX_ErrorBadParameter;
3284 break;
3285 }
Arun Menon906de572013-06-18 17:01:40 -07003286 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3287 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3288 port_format_changed = true;
3289 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3290 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3291 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3292 (~(buffer_prop->alignment - 1));
3293 eRet = set_buffer_req(buffer_prop);
3294 }
3295 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003296 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003297 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3298 portDefn->nBufferCountActual, portDefn->nBufferSize);
3299 eRet = OMX_ErrorBadParameter;
3300 }
3301 } else if (portDefn->eDir == OMX_DirMax) {
3302 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3303 (int)portDefn->nPortIndex);
3304 eRet = OMX_ErrorBadPortIndex;
3305 }
3306 }
3307 break;
3308 case OMX_IndexParamVideoPortFormat: {
3309 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3310 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3311 int ret=0;
3312 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003313 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003314 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003315
Arun Menon906de572013-06-18 17:01:40 -07003316 if (1 == portFmt->nPortIndex) {
3317 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3318 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3319 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3320 fmt.fmt.pix_mp.pixelformat = capture_capability;
3321 enum vdec_output_fromat op_format;
3322 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3323 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Praveen Chavandb7776f2014-02-06 18:17:25 -08003324 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
3325 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar))
Arun Menon906de572013-06-18 17:01:40 -07003326 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Arun Menon906de572013-06-18 17:01:40 -07003327 else
3328 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003329
Arun Menon906de572013-06-18 17:01:40 -07003330 if (eRet == OMX_ErrorNone) {
3331 drv_ctx.output_format = op_format;
3332 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3333 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003334 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003335 eRet = OMX_ErrorUnsupportedSetting;
3336 /*TODO: How to handle this case */
3337 } else {
3338 eRet = get_buffer_req(&drv_ctx.op_buf);
3339 }
3340 }
3341 if (eRet == OMX_ErrorNone) {
3342 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003343 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003344 eRet = OMX_ErrorBadParameter;
3345 }
3346 }
3347 }
3348 }
3349 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003350
Arun Menon906de572013-06-18 17:01:40 -07003351 case OMX_QcomIndexPortDefn: {
3352 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3353 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003354 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003355 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003356
Arun Menon906de572013-06-18 17:01:40 -07003357 /* Input port */
3358 if (portFmt->nPortIndex == 0) {
3359 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3360 if (secure_mode) {
3361 arbitrary_bytes = false;
3362 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3363 eRet = OMX_ErrorUnsupportedSetting;
3364 } else {
3365 arbitrary_bytes = true;
3366 }
3367 } else if (portFmt->nFramePackingFormat ==
3368 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3369 arbitrary_bytes = false;
3370 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003371 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003372 portFmt->nFramePackingFormat);
3373 eRet = OMX_ErrorUnsupportedSetting;
3374 }
3375 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003376 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003377 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3378 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3379 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3380 m_out_mem_region_smi = OMX_TRUE;
3381 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003382 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003383 m_use_output_pmem = OMX_TRUE;
3384 }
3385 }
3386 }
3387 }
3388 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003389
Arun Menon906de572013-06-18 17:01:40 -07003390 case OMX_IndexParamStandardComponentRole: {
3391 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3392 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003393 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003394 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003395
Arun Menon906de572013-06-18 17:01:40 -07003396 if ((m_state == OMX_StateLoaded)&&
3397 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3398 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3399 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003400 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003401 return OMX_ErrorIncorrectStateOperation;
3402 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003403
Arun Menon906de572013-06-18 17:01:40 -07003404 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3405 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3406 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3407 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003408 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003409 eRet =OMX_ErrorUnsupportedSetting;
3410 }
3411 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3412 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3413 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3414 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003415 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003416 eRet = OMX_ErrorUnsupportedSetting;
3417 }
3418 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3419 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3420 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3421 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003422 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003423 eRet =OMX_ErrorUnsupportedSetting;
3424 }
3425 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3426 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3427 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3428 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003429 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003430 eRet = OMX_ErrorUnsupportedSetting;
3431 }
3432 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
Deva Ramasubramanianba4534b2013-12-17 15:52:37 -08003433 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) ||
3434 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE))
Arun Menon906de572013-06-18 17:01:40 -07003435 ) {
3436 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3437 strlcpy((char*)m_cRole,"video_decoder.divx",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.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3443 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3444 ) {
3445 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3446 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3447 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003448 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003449 eRet =OMX_ErrorUnsupportedSetting;
3450 }
3451 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3452 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3453 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3454 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3455 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003456 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003457 eRet = OMX_ErrorUnsupportedSetting;
3458 }
3459 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003460 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003461 eRet = OMX_ErrorInvalidComponentName;
3462 }
3463 break;
3464 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003465
Arun Menon906de572013-06-18 17:01:40 -07003466 case OMX_IndexParamPriorityMgmt: {
3467 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003468 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003469 return OMX_ErrorIncorrectStateOperation;
3470 }
3471 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003472 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003473 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003474
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003475 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003476 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003477
Arun Menon906de572013-06-18 17:01:40 -07003478 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3479 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003480
Arun Menon906de572013-06-18 17:01:40 -07003481 break;
3482 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003483
Arun Menon906de572013-06-18 17:01:40 -07003484 case OMX_IndexParamCompBufferSupplier: {
3485 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003486 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003487 bufferSupplierType->eBufferSupplier);
3488 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3489 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003490
Arun Menon906de572013-06-18 17:01:40 -07003491 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003492
Arun Menon906de572013-06-18 17:01:40 -07003493 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003494
Arun Menon906de572013-06-18 17:01:40 -07003495 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003496
Arun Menon906de572013-06-18 17:01:40 -07003497 }
3498 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003499 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003500 paramIndex);
3501 break;
3502 }
3503 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003504 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003505 paramIndex);
3506 break;
3507 }
3508 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003509 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003510 paramIndex);
3511 break;
3512 }
3513 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003514 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003515 paramIndex);
3516 break;
3517 }
3518 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3519 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3520 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3521 struct v4l2_control control;
3522 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003523 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003524 pictureOrder->eOutputPictureOrder);
3525 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3526 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3527 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3528 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3529 time_stamp_dts.set_timestamp_reorder_mode(false);
3530 } else
3531 eRet = OMX_ErrorBadParameter;
3532 if (eRet == OMX_ErrorNone) {
3533 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3534 control.value = pic_order;
3535 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3536 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003537 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003538 eRet = OMX_ErrorUnsupportedSetting;
3539 }
3540 }
3541 break;
3542 }
3543 case OMX_QcomIndexParamConcealMBMapExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303544 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3545 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3546 break;
3547 case OMX_QcomIndexParamFrameInfoExtraData:
3548 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3549 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3550 break;
Arun Menon906de572013-06-18 17:01:40 -07003551 case OMX_QcomIndexParamInterlaceExtraData:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303552 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3553 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3554 break;
Arun Menon906de572013-06-18 17:01:40 -07003555 case OMX_QcomIndexParamH264TimeInfo:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303556 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3557 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3558 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303559 case OMX_QcomIndexParamVideoFramePackingExtradata:
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303560 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3561 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3562 break;
3563 case OMX_QcomIndexParamVideoQPExtraData:
3564 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
3565 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3566 break;
3567 case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
3568 eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
3569 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3570 break;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05303571 case OMX_QcomIndexEnableExtnUserData:
3572 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
3573 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3574 break;
Arun Menon906de572013-06-18 17:01:40 -07003575 case OMX_QcomIndexParamVideoDivx: {
3576 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3577 }
3578 break;
3579 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003580 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003581 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3582 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3583 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3584 eRet = OMX_ErrorUnsupportedSetting;
3585 } else {
3586 m_out_pvt_entry_pmem = OMX_TRUE;
3587 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003588 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003589 m_use_output_pmem = OMX_TRUE;
3590 }
3591 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003592
Arun Menon906de572013-06-18 17:01:40 -07003593 }
3594 break;
3595 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3596 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3597 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3598 struct v4l2_control control;
3599 int rc;
3600 drv_ctx.idr_only_decoding = 1;
3601 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3602 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3603 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3604 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003605 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003606 eRet = OMX_ErrorUnsupportedSetting;
3607 } else {
3608 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3609 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3610 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3611 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003612 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003613 eRet = OMX_ErrorUnsupportedSetting;
3614 }
3615 /*Setting sync frame decoding on driver might change buffer
3616 * requirements so update them here*/
3617 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003618 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003619 eRet = OMX_ErrorUnsupportedSetting;
3620 }
3621 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003622 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003623 eRet = OMX_ErrorUnsupportedSetting;
3624 }
3625 }
3626 }
3627 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003628
Arun Menon906de572013-06-18 17:01:40 -07003629 case OMX_QcomIndexParamIndexExtraDataType: {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05303630 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3631 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3632 (extradataIndexType->bEnabled == OMX_TRUE) &&
3633 (extradataIndexType->nPortIndex == 1)) {
3634 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
3635 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
3636 }
3637 }
Arun Menon906de572013-06-18 17:01:40 -07003638 break;
3639 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003640#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003641 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003642#else
Arun Menon906de572013-06-18 17:01:40 -07003643 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003644#endif
Arun Menon906de572013-06-18 17:01:40 -07003645 }
3646 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003647#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003648 /* Need to allow following two set_parameters even in Idle
3649 * state. This is ANDROID architecture which is not in sync
3650 * with openmax standard. */
3651 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3652 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3653 if (enableNativeBuffers) {
3654 m_enable_android_native_buffers = enableNativeBuffers->enable;
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07003655 }
Praveen Chavancac86402014-10-18 09:14:52 -07003656#if !defined(FLEXYUV_SUPPORTED)
Manikanta Kanamarlapudi78b7fb62014-04-04 11:46:02 -07003657 if (m_enable_android_native_buffers) {
3658 // Use the most-preferred-native-color-format as surface-mode is hinted here
3659 if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
3660 DEBUG_PRINT_ERROR("Failed to set native color format!");
3661 eRet = OMX_ErrorUnsupportedSetting;
3662 }
Arun Menon906de572013-06-18 17:01:40 -07003663 }
Praveen Chavancac86402014-10-18 09:14:52 -07003664#endif
Arun Menon906de572013-06-18 17:01:40 -07003665 }
3666 break;
3667 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3668 eRet = use_android_native_buffer(hComp, paramData);
3669 }
3670 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003671#endif
Arun Menon906de572013-06-18 17:01:40 -07003672 case OMX_QcomIndexParamEnableTimeStampReorder: {
3673 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3674 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3675 if (reorder->bEnable == OMX_TRUE) {
3676 frm_int =0;
3677 time_stamp_dts.set_timestamp_reorder_mode(true);
3678 } else
3679 time_stamp_dts.set_timestamp_reorder_mode(false);
3680 } else {
3681 time_stamp_dts.set_timestamp_reorder_mode(false);
3682 if (reorder->bEnable == OMX_TRUE) {
3683 eRet = OMX_ErrorUnsupportedSetting;
3684 }
3685 }
3686 }
3687 break;
3688 case OMX_IndexParamVideoProfileLevelCurrent: {
3689 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3690 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3691 if (pParam) {
3692 m_profile_lvl.eProfile = pParam->eProfile;
3693 m_profile_lvl.eLevel = pParam->eLevel;
3694 }
3695 break;
Arun Menon888aa852013-05-30 11:24:42 -07003696
Arun Menon906de572013-06-18 17:01:40 -07003697 }
Arun Menone5652482013-08-04 13:33:05 -07003698 case OMX_QcomIndexParamVideoMetaBufferMode:
3699 {
3700 StoreMetaDataInBuffersParams *metabuffer =
3701 (StoreMetaDataInBuffersParams *)paramData;
3702 if (!metabuffer) {
3703 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3704 eRet = OMX_ErrorBadParameter;
3705 break;
3706 }
3707 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3708 //set property dynamic buffer mode to driver.
3709 struct v4l2_control control;
3710 struct v4l2_format fmt;
3711 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3712 if (metabuffer->bStoreMetaData == true) {
3713 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3714 } else {
3715 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3716 }
3717 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3718 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003719 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003720 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003721 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003722 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003723 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003724 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3725 eRet = OMX_ErrorUnsupportedSetting;
3726 }
3727 } else {
3728 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003729 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003730 metabuffer->nPortIndex);
3731 eRet = OMX_ErrorUnsupportedSetting;
3732 }
3733 break;
3734 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003735 case OMX_QcomIndexParamVideoDownScalar: {
3736 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3737 struct v4l2_control control;
3738 int rc;
3739 if (pParam) {
3740 is_down_scalar_enabled = pParam->bEnable;
3741 if (is_down_scalar_enabled) {
3742 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3743 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3744 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3745 pParam->bEnable);
3746 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3747 if (rc < 0) {
3748 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3749 eRet = OMX_ErrorUnsupportedSetting;
3750 }
3751 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3752 control.value = 1;
3753 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3754 if (rc < 0) {
3755 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3756 eRet = OMX_ErrorUnsupportedSetting;
3757 }
3758 }
3759 }
3760 break;
3761 }
Praveen Chavancf924182013-12-06 23:16:23 -08003762#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3763 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3764 {
3765 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3766 PrepareForAdaptivePlaybackParams* pParams =
3767 (PrepareForAdaptivePlaybackParams *) paramData;
3768 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3769 if (!pParams->bEnable) {
3770 return OMX_ErrorNone;
3771 }
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303772 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
3773 || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
Praveen Chavancf924182013-12-06 23:16:23 -08003774 DEBUG_PRINT_ERROR(
3775 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3776 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
Deepak Vermaa2efdb12013-12-26 12:30:05 +05303777 maxSmoothStreamingWidth, maxSmoothStreamingHeight);
Praveen Chavancf924182013-12-06 23:16:23 -08003778 eRet = OMX_ErrorBadParameter;
3779 } else {
Arun Menon1fc764f2014-04-17 15:41:27 -07003780 eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3781 }
Praveen Chavancf924182013-12-06 23:16:23 -08003782 } else {
3783 DEBUG_PRINT_ERROR(
3784 "Prepare for adaptive playback supported only on output port");
3785 eRet = OMX_ErrorBadParameter;
3786 }
3787 break;
3788 }
3789
3790#endif
Pushkaraj Patil8d273cb2014-07-21 10:43:22 +05303791 case OMX_QcomIndexParamVideoCustomBufferSize:
3792 {
3793 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
3794 QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
3795 if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3796 struct v4l2_control control;
3797 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
3798 control.value = pParam->nBufferSize;
3799 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
3800 DEBUG_PRINT_ERROR("Failed to set input buffer size");
3801 eRet = OMX_ErrorUnsupportedSetting;
3802 } else {
3803 eRet = get_buffer_req(&drv_ctx.ip_buf);
3804 if (eRet == OMX_ErrorNone) {
3805 m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
3806 DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
3807 m_custom_buffersize.input_buffersize);
3808 } else {
3809 DEBUG_PRINT_ERROR("Failed to get buffer requirement");
3810 }
3811 }
3812 } else {
3813 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
3814 eRet = OMX_ErrorBadParameter;
3815 }
3816 break;
3817 }
Arun Menon906de572013-06-18 17:01:40 -07003818 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003819 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003820 eRet = OMX_ErrorUnsupportedIndex;
3821 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003822 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08003823 if (eRet != OMX_ErrorNone)
3824 DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003825 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003826}
3827
3828/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003829 FUNCTION
3830 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003831
Arun Menon906de572013-06-18 17:01:40 -07003832 DESCRIPTION
3833 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003834
Arun Menon906de572013-06-18 17:01:40 -07003835 PARAMETERS
3836 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003837
Arun Menon906de572013-06-18 17:01:40 -07003838 RETURN VALUE
3839 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003840
Arun Menon906de572013-06-18 17:01:40 -07003841 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003842OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003843 OMX_IN OMX_INDEXTYPE configIndex,
3844 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003845{
Arun Menon906de572013-06-18 17:01:40 -07003846 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003847
Arun Menon906de572013-06-18 17:01:40 -07003848 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003849 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003850 return OMX_ErrorInvalidState;
3851 }
Arun Menon906de572013-06-18 17:01:40 -07003852
3853 switch ((unsigned long)configIndex) {
3854 case OMX_QcomIndexConfigInterlaced: {
3855 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3856 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3857 if (configFmt->nPortIndex == 1) {
3858 if (configFmt->nIndex == 0) {
3859 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3860 } else if (configFmt->nIndex == 1) {
3861 configFmt->eInterlaceType =
3862 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3863 } else if (configFmt->nIndex == 2) {
3864 configFmt->eInterlaceType =
3865 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3866 } else {
3867 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003868 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003869 eRet = OMX_ErrorNoMore;
3870 }
3871
3872 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003873 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003874 (int)configFmt->nPortIndex);
3875 eRet = OMX_ErrorBadPortIndex;
3876 }
3877 break;
3878 }
3879 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3880 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3881 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3882 decoderinstances->nNumOfInstances = 16;
3883 /*TODO: How to handle this case */
3884 break;
3885 }
3886 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3887 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3888 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3889 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303890 memcpy(configFmt, &m_frame_pack_arrangement,
3891 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003892 } else {
3893 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3894 }
3895 break;
3896 }
3897 case OMX_IndexConfigCommonOutputCrop: {
3898 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3899 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05303900 DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
3901 rectangle.nLeft, rectangle.nTop,
3902 rectangle.nWidth, rectangle.nHeight);
Arun Menon906de572013-06-18 17:01:40 -07003903 break;
3904 }
3905 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003906 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003907 eRet = OMX_ErrorBadParameter;
3908 }
3909
Shalaj Jain273b3e02012-06-22 19:08:03 -07003910 }
Arun Menon906de572013-06-18 17:01:40 -07003911
3912 return eRet;
3913}
3914
3915/* ======================================================================
3916 FUNCTION
3917 omx_vdec::SetConfig
3918
3919 DESCRIPTION
3920 OMX Set Config method implementation
3921
3922 PARAMETERS
3923 <TBD>.
3924
3925 RETURN VALUE
3926 OMX Error None if successful.
3927 ========================================================================== */
3928OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3929 OMX_IN OMX_INDEXTYPE configIndex,
3930 OMX_IN OMX_PTR configData)
3931{
3932 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003933 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003934 return OMX_ErrorInvalidState;
3935 }
3936
3937 OMX_ERRORTYPE ret = OMX_ErrorNone;
3938 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3939
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003940 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003941
3942 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3943 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003944 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003945 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003946 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003947 OMX_U32 extra_size;
3948 // Parsing done here for the AVC atom is definitely not generic
3949 // Currently this piece of code is working, but certainly
3950 // not tested with all .mp4 files.
3951 // Incase of failure, we might need to revisit this
3952 // for a generic piece of code.
3953
3954 // Retrieve size of NAL length field
3955 // byte #4 contains the size of NAL lenght field
3956 nal_length = (config->pData[4] & 0x03) + 1;
3957
3958 extra_size = 0;
3959 if (nal_length > 2) {
3960 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3961 extra_size = (nal_length - 2) * 2;
3962 }
3963
3964 // SPS starts from byte #6
3965 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3966 OMX_U8 *pDestBuf;
3967 m_vendor_config.nPortIndex = config->nPortIndex;
3968
3969 // minus 6 --> SPS starts from byte #6
3970 // minus 1 --> picture param set byte to be ignored from avcatom
3971 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3972 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3973 OMX_U32 len;
3974 OMX_U8 index = 0;
3975 // case where SPS+PPS is sent as part of set_config
3976 pDestBuf = m_vendor_config.pData;
3977
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003978 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003979 m_vendor_config.nPortIndex,
3980 m_vendor_config.nDataSize,
3981 m_vendor_config.pData);
3982 while (index < 2) {
3983 uint8 *psize;
3984 len = *pSrcBuf;
3985 len = len << 8;
3986 len |= *(pSrcBuf + 1);
3987 psize = (uint8 *) & len;
3988 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3989 for (unsigned int i = 0; i < nal_length; i++) {
3990 pDestBuf[i] = psize[nal_length - 1 - i];
3991 }
3992 //memcpy(pDestBuf,pSrcBuf,(len+2));
3993 pDestBuf += len + nal_length;
3994 pSrcBuf += len + 2;
3995 index++;
3996 pSrcBuf++; // skip picture param set
3997 len = 0;
3998 }
3999 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
4000 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
4001 m_vendor_config.nPortIndex = config->nPortIndex;
4002 m_vendor_config.nDataSize = config->nDataSize;
4003 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
4004 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
4005 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
4006 if (m_vendor_config.pData) {
4007 free(m_vendor_config.pData);
4008 m_vendor_config.pData = NULL;
4009 m_vendor_config.nDataSize = 0;
4010 }
4011
4012 if (((*((OMX_U32 *) config->pData)) &
4013 VC1_SP_MP_START_CODE_MASK) ==
4014 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004015 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07004016 m_vendor_config.nPortIndex = config->nPortIndex;
4017 m_vendor_config.nDataSize = config->nDataSize;
4018 m_vendor_config.pData =
4019 (OMX_U8 *) malloc(config->nDataSize);
4020 memcpy(m_vendor_config.pData, config->pData,
4021 config->nDataSize);
4022 m_vc1_profile = VC1_SP_MP_RCV;
4023 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004024 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07004025 m_vendor_config.nPortIndex = config->nPortIndex;
4026 m_vendor_config.nDataSize = config->nDataSize;
4027 m_vendor_config.pData =
4028 (OMX_U8 *) malloc((config->nDataSize));
4029 memcpy(m_vendor_config.pData, config->pData,
4030 config->nDataSize);
4031 m_vc1_profile = VC1_AP;
4032 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004033 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07004034 m_vendor_config.nPortIndex = config->nPortIndex;
4035 m_vendor_config.nDataSize = config->nDataSize;
4036 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
4037 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
4038 m_vc1_profile = VC1_SP_MP_RCV;
4039 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004040 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07004041 }
4042 }
4043 return ret;
4044 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
4045 struct v4l2_control temp;
4046 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
4047
4048 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
4049 switch (pNal->nNaluBytes) {
4050 case 0:
4051 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
4052 break;
4053 case 2:
4054 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
4055 break;
4056 case 4:
4057 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
4058 break;
4059 default:
4060 return OMX_ErrorUnsupportedSetting;
4061 }
4062
4063 if (!arbitrary_bytes) {
4064 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
4065 * with start code, so only need to notify driver in frame by frame mode */
4066 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
4067 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
4068 return OMX_ErrorHardware;
4069 }
4070 }
4071
4072 nal_length = pNal->nNaluBytes;
4073 m_frame_parser.init_nal_length(nal_length);
4074
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004075 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07004076 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05304077 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07004078 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05304079 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07004080
4081 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
4082 if (config->bEnabled) {
4083 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05304084 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07004085 config->nFps >> 16);
4086 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
4087 drv_ctx.frame_rate.fps_denominator);
4088
4089 if (!drv_ctx.frame_rate.fps_numerator) {
4090 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
4091 drv_ctx.frame_rate.fps_numerator = 30;
4092 }
4093
4094 if (drv_ctx.frame_rate.fps_denominator) {
4095 drv_ctx.frame_rate.fps_numerator = (int)
4096 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
4097 }
4098
4099 drv_ctx.frame_rate.fps_denominator = 1;
4100 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
4101 drv_ctx.frame_rate.fps_numerator;
4102
4103 struct v4l2_outputparm oparm;
4104 /*XXX: we're providing timing info as seconds per frame rather than frames
4105 * per second.*/
4106 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
4107 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
4108
4109 struct v4l2_streamparm sparm;
4110 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4111 sparm.parm.output = oparm;
4112 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
4113 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
4114 performance might be affected");
4115 ret = OMX_ErrorHardware;
4116 }
4117 client_set_fps = true;
4118 } else {
4119 DEBUG_PRINT_ERROR("Frame rate not supported.");
4120 ret = OMX_ErrorUnsupportedSetting;
4121 }
4122 } else {
4123 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
4124 client_set_fps = false;
4125 }
4126 } else {
4127 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
4128 (int)config->nPortIndex);
4129 ret = OMX_ErrorBadPortIndex;
4130 }
4131
4132 return ret;
Praveen Chavan898df262015-04-20 18:52:19 -07004133 } else if ((int)configIndex == (int)OMX_IndexConfigPriority) {
4134 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
4135 DEBUG_PRINT_LOW("Set_config: priority %d", priority->nU32);
4136
4137 struct v4l2_control control;
4138
4139 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
4140 if (priority->nU32 == 0)
4141 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
4142 else
4143 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
4144
4145 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
4146 DEBUG_PRINT_ERROR("Failed to set Priority");
4147 ret = OMX_ErrorUnsupportedSetting;
4148 }
4149 return ret;
Praveen Chavan281d5022015-04-30 20:28:44 -07004150 } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) {
4151 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
4152 DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16);
4153
4154 struct v4l2_control control;
4155
4156 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
4157 control.value = rate->nU32;
4158
4159 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
4160 ret = errno == -EBUSY ? OMX_ErrorInsufficientResources :
4161 OMX_ErrorUnsupportedSetting;
4162 DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)",
4163 rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno));
4164 }
4165 return ret;
Arun Menon906de572013-06-18 17:01:40 -07004166 }
4167
4168 return OMX_ErrorNotImplemented;
4169}
4170
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304171#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
4172
Arun Menon906de572013-06-18 17:01:40 -07004173/* ======================================================================
4174 FUNCTION
4175 omx_vdec::GetExtensionIndex
4176
4177 DESCRIPTION
4178 OMX GetExtensionIndex method implementaion. <TBD>
4179
4180 PARAMETERS
4181 <TBD>.
4182
4183 RETURN VALUE
4184 OMX Error None if everything successful.
4185
4186 ========================================================================== */
4187OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
4188 OMX_IN OMX_STRING paramName,
4189 OMX_OUT OMX_INDEXTYPE* indexType)
4190{
4191 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004192 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004193 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304194 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07004195 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304196 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004197 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304198 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
4199 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
4200 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
4201 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08004202 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
4203 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08004204 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
4205 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08004206 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
4207 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004208 }
4209#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304210 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004211 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304212 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004213 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304214 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004215 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004216 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304217 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004218 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
4219 }
4220#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05304221 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07004222 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
4223 }
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05304224#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Praveen Chavancf924182013-12-06 23:16:23 -08004225 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
4226 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
4227 }
4228#endif
Praveen Chavan09a82b72014-10-18 09:09:45 -07004229#ifdef FLEXYUV_SUPPORTED
4230 else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
4231 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
4232 }
4233#endif
Arun Menon906de572013-06-18 17:01:40 -07004234 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004235 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004236 return OMX_ErrorNotImplemented;
4237 }
4238 return OMX_ErrorNone;
4239}
4240
4241/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004242 FUNCTION
4243 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07004244
Arun Menon906de572013-06-18 17:01:40 -07004245 DESCRIPTION
4246 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004247
Arun Menon906de572013-06-18 17:01:40 -07004248 PARAMETERS
4249 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004250
Arun Menon906de572013-06-18 17:01:40 -07004251 RETURN VALUE
4252 Error None if everything is successful.
4253 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004254OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004255 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004256{
Arun Menon906de572013-06-18 17:01:40 -07004257 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004258 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07004259 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004260}
4261
4262/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004263 FUNCTION
4264 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07004265
Arun Menon906de572013-06-18 17:01:40 -07004266 DESCRIPTION
4267 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07004268
Arun Menon906de572013-06-18 17:01:40 -07004269 PARAMETERS
4270 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004271
Arun Menon906de572013-06-18 17:01:40 -07004272 RETURN VALUE
4273 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004274
Arun Menon906de572013-06-18 17:01:40 -07004275 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004276OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004277 OMX_IN OMX_U32 port,
4278 OMX_IN OMX_HANDLETYPE peerComponent,
4279 OMX_IN OMX_U32 peerPort,
4280 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004281{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004282 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07004283 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004284}
4285
4286/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004287 FUNCTION
4288 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004289
Arun Menon906de572013-06-18 17:01:40 -07004290 DESCRIPTION
4291 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004292
Arun Menon906de572013-06-18 17:01:40 -07004293 PARAMETERS
4294 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004295
Arun Menon906de572013-06-18 17:01:40 -07004296 RETURN VALUE
4297 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004298
Arun Menon906de572013-06-18 17:01:40 -07004299 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004300OMX_ERRORTYPE omx_vdec::allocate_extradata()
4301{
4302#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004303 if (drv_ctx.extradata_info.buffer_size) {
4304 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4305 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4306 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4307 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004308 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004309 }
4310 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4311 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4312 drv_ctx.extradata_info.size, 4096,
4313 &drv_ctx.extradata_info.ion.ion_alloc_data,
4314 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4315 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004316 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004317 return OMX_ErrorInsufficientResources;
4318 }
4319 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4320 drv_ctx.extradata_info.size,
4321 PROT_READ|PROT_WRITE, MAP_SHARED,
4322 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4323 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004324 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004325 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4326 free_ion_memory(&drv_ctx.extradata_info.ion);
4327 return OMX_ErrorInsufficientResources;
4328 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004329 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004330#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304331 if (!m_other_extradata) {
4332 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4333 if (!m_other_extradata) {
4334 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4335 return OMX_ErrorInsufficientResources;
4336 }
4337 }
Arun Menon906de572013-06-18 17:01:40 -07004338 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004339}
4340
Arun Menon906de572013-06-18 17:01:40 -07004341void omx_vdec::free_extradata()
4342{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004343#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004344 if (drv_ctx.extradata_info.uaddr) {
4345 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4346 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4347 free_ion_memory(&drv_ctx.extradata_info.ion);
4348 }
4349 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004350#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304351 if (m_other_extradata) {
4352 free(m_other_extradata);
4353 m_other_extradata = NULL;
4354 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004355}
4356
Shalaj Jain273b3e02012-06-22 19:08:03 -07004357OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004358 OMX_IN OMX_HANDLETYPE hComp,
4359 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4360 OMX_IN OMX_U32 port,
4361 OMX_IN OMX_PTR appData,
4362 OMX_IN OMX_U32 bytes,
4363 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004364{
Arun Menon906de572013-06-18 17:01:40 -07004365 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4366 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4367 unsigned i= 0; // Temporary counter
4368 struct vdec_setbuffer_cmd setbuffers;
4369 OMX_PTR privateAppData = NULL;
4370 private_handle_t *handle = NULL;
4371 OMX_U8 *buff = buffer;
4372 struct v4l2_buffer buf;
4373 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4374 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004375
Arun Menon906de572013-06-18 17:01:40 -07004376 if (!m_out_mem_ptr) {
4377 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4378 eRet = allocate_output_headers();
4379 if (eRet == OMX_ErrorNone)
4380 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004381 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004382
Arun Menon906de572013-06-18 17:01:40 -07004383 if (eRet == OMX_ErrorNone) {
4384 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4385 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4386 break;
4387 }
4388 }
4389 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004390
Arun Menon906de572013-06-18 17:01:40 -07004391 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004392 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004393 eRet = OMX_ErrorInsufficientResources;
4394 }
4395
Arun Menonbdb80b02013-08-12 17:45:54 -07004396 if (dynamic_buf_mode) {
4397 *bufferHdr = (m_out_mem_ptr + i );
4398 (*bufferHdr)->pBuffer = NULL;
4399 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4400 enum v4l2_buf_type buf_type;
4401 int rr = 0;
4402 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4403 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4404 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4405 return OMX_ErrorInsufficientResources;
4406 } else {
4407 streaming[CAPTURE_PORT] = true;
4408 DEBUG_PRINT_LOW("STREAMON Successful");
4409 }
4410 }
4411 BITMASK_SET(&m_out_bm_count,i);
4412 (*bufferHdr)->pAppPrivate = appData;
4413 (*bufferHdr)->pBuffer = buffer;
4414 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4415 return eRet;
4416 }
Arun Menon906de572013-06-18 17:01:40 -07004417 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004418#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004419 if (m_enable_android_native_buffers) {
4420 if (m_use_android_native_buffers) {
4421 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4422 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4423 handle = (private_handle_t *)nBuf->handle;
4424 privateAppData = params->pAppPrivate;
4425 } else {
4426 handle = (private_handle_t *)buff;
4427 privateAppData = appData;
4428 }
Arun Menon8544ead2014-05-08 17:42:29 -07004429 if (!handle) {
4430 DEBUG_PRINT_ERROR("handle is invalid");
4431 return OMX_ErrorBadParameter;
4432 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004433
Arun Menon906de572013-06-18 17:01:40 -07004434 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4435 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4436 " expected %u, got %lu",
4437 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4438 return OMX_ErrorBadParameter;
4439 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004440
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07004441 drv_ctx.op_buf.buffer_size = handle->size;
4442
Arun Menon906de572013-06-18 17:01:40 -07004443 if (!m_use_android_native_buffers) {
4444 if (!secure_mode) {
4445 buff = (OMX_U8*)mmap(0, handle->size,
4446 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4447 if (buff == MAP_FAILED) {
4448 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4449 return OMX_ErrorInsufficientResources;
4450 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004451 }
4452 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004453#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004454 native_buffer[i].nativehandle = handle;
4455 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004456#endif
Arun Menon906de572013-06-18 17:01:40 -07004457 if (!handle) {
4458 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4459 return OMX_ErrorBadParameter;
4460 }
4461 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4462 drv_ctx.ptr_outputbuffer[i].offset = 0;
4463 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4464 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4465 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4466 } else
4467#endif
4468
4469 if (!ouput_egl_buffers && !m_use_output_pmem) {
4470#ifdef USE_ION
4471 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4472 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4473 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4474 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4475 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004476 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 -07004477 return OMX_ErrorInsufficientResources;
4478 }
4479 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4480 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4481#else
4482 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4483 open (MEM_DEVICE,O_RDWR);
4484
4485 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004486 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004487 return OMX_ErrorInsufficientResources;
4488 }
4489
4490 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4491 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4492 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4493 open (MEM_DEVICE,O_RDWR);
4494 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004495 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004496 return OMX_ErrorInsufficientResources;
4497 }
4498 }
4499
4500 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4501 drv_ctx.op_buf.buffer_size,
4502 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004503 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004504 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4505 return OMX_ErrorInsufficientResources;
4506 }
4507#endif
4508 if (!secure_mode) {
4509 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4510 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4511 PROT_READ|PROT_WRITE, MAP_SHARED,
4512 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4513 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4514 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4515#ifdef USE_ION
4516 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4517#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004518 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004519 return OMX_ErrorInsufficientResources;
4520 }
4521 }
4522 drv_ctx.ptr_outputbuffer[i].offset = 0;
4523 privateAppData = appData;
4524 } else {
4525
4526 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4527 if (!appData || !bytes ) {
4528 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004529 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004530 return OMX_ErrorBadParameter;
4531 }
4532 }
4533
4534 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4535 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4536 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
Arun Menon8544ead2014-05-08 17:42:29 -07004537 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
Arun Menon906de572013-06-18 17:01:40 -07004538 !pmem_list->nEntries ||
4539 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004540 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004541 return OMX_ErrorBadParameter;
4542 }
4543 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4544 pmem_list->entryList->entry;
4545 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4546 pmem_info->pmem_fd);
4547 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4548 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4549 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4550 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4551 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4552 privateAppData = appData;
4553 }
4554 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4555 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304556 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4557 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4558 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004559
4560 *bufferHdr = (m_out_mem_ptr + i );
4561 if (secure_mode)
4562 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4563 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4564 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4565 sizeof (vdec_bufferpayload));
4566
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004567 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004568 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4569 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4570
4571 buf.index = i;
4572 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4573 buf.memory = V4L2_MEMORY_USERPTR;
4574 plane[0].length = drv_ctx.op_buf.buffer_size;
4575 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4576 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4577 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4578 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4579 plane[0].data_offset = 0;
4580 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4581 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4582 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4583 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4584#ifdef USE_ION
4585 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4586#endif
4587 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4588 plane[extra_idx].data_offset = 0;
4589 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004590 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004591 return OMX_ErrorBadParameter;
4592 }
Arun Menon906de572013-06-18 17:01:40 -07004593 buf.m.planes = plane;
4594 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004595
Arun Menon906de572013-06-18 17:01:40 -07004596 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004597 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004598 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004599 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004600 }
4601
Arun Menon906de572013-06-18 17:01:40 -07004602 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4603 enum v4l2_buf_type buf_type;
4604 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4605 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4606 return OMX_ErrorInsufficientResources;
4607 } else {
4608 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004609 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004610 }
4611 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004612
Arun Menon906de572013-06-18 17:01:40 -07004613 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4614 if (m_enable_android_native_buffers) {
4615 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4616 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4617 } else {
4618 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004619 }
Arun Menon906de572013-06-18 17:01:40 -07004620 (*bufferHdr)->pAppPrivate = privateAppData;
4621 BITMASK_SET(&m_out_bm_count,i);
4622 }
4623 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004624}
4625
4626/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004627 FUNCTION
4628 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004629
Arun Menon906de572013-06-18 17:01:40 -07004630 DESCRIPTION
4631 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004632
Arun Menon906de572013-06-18 17:01:40 -07004633 PARAMETERS
4634 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004635
Arun Menon906de572013-06-18 17:01:40 -07004636 RETURN VALUE
4637 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004638
Arun Menon906de572013-06-18 17:01:40 -07004639 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004640OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004641 OMX_IN OMX_HANDLETYPE hComp,
4642 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4643 OMX_IN OMX_U32 port,
4644 OMX_IN OMX_PTR appData,
4645 OMX_IN OMX_U32 bytes,
4646 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004647{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004648 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004649 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4650 if (!m_inp_heap_ptr)
4651 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4652 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4653 drv_ctx.ip_buf.actualcount);
4654 if (!m_phdr_pmem_ptr)
4655 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4656 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4657 drv_ctx.ip_buf.actualcount);
4658 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4659 DEBUG_PRINT_ERROR("Insufficent memory");
4660 eRet = OMX_ErrorInsufficientResources;
4661 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4662 input_use_buffer = true;
4663 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4664 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4665 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4666 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4667 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4668 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4669 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4670 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004671 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 -07004672 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4673 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004674 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004675 return OMX_ErrorInsufficientResources;
4676 }
4677 m_in_alloc_cnt++;
4678 } else {
4679 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4680 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004681 }
Arun Menon906de572013-06-18 17:01:40 -07004682 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004683}
4684
4685/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004686 FUNCTION
4687 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004688
Arun Menon906de572013-06-18 17:01:40 -07004689 DESCRIPTION
4690 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004691
Arun Menon906de572013-06-18 17:01:40 -07004692 PARAMETERS
4693 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004694
Arun Menon906de572013-06-18 17:01:40 -07004695 RETURN VALUE
4696 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004697
Arun Menon906de572013-06-18 17:01:40 -07004698 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004699OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004700 OMX_IN OMX_HANDLETYPE hComp,
4701 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4702 OMX_IN OMX_U32 port,
4703 OMX_IN OMX_PTR appData,
4704 OMX_IN OMX_U32 bytes,
4705 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004706{
Arun Menon906de572013-06-18 17:01:40 -07004707 OMX_ERRORTYPE error = OMX_ErrorNone;
4708 struct vdec_setbuffer_cmd setbuffers;
4709
Arun Menon8544ead2014-05-08 17:42:29 -07004710 if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
4711 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4712 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004713 }
Arun Menon906de572013-06-18 17:01:40 -07004714 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004715 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004716 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004717 }
Arun Menon906de572013-06-18 17:01:40 -07004718 if (port == OMX_CORE_INPUT_PORT_INDEX)
4719 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4720 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4721 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4722 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004723 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004724 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004725 }
Arun Menon906de572013-06-18 17:01:40 -07004726 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4727 if (error == OMX_ErrorNone) {
4728 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4729 // Send the callback now
4730 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4731 post_event(OMX_CommandStateSet,OMX_StateIdle,
4732 OMX_COMPONENT_GENERATE_EVENT);
4733 }
4734 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4735 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4736 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4737 post_event(OMX_CommandPortEnable,
4738 OMX_CORE_INPUT_PORT_INDEX,
4739 OMX_COMPONENT_GENERATE_EVENT);
4740 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4741 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4742 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4743 post_event(OMX_CommandPortEnable,
4744 OMX_CORE_OUTPUT_PORT_INDEX,
4745 OMX_COMPONENT_GENERATE_EVENT);
4746 }
4747 }
4748 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004749}
4750
4751OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004752 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004753{
Arun Menon906de572013-06-18 17:01:40 -07004754 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4755 if (m_inp_heap_ptr[bufferindex].pBuffer)
4756 free(m_inp_heap_ptr[bufferindex].pBuffer);
4757 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4758 }
4759 if (pmem_bufferHdr)
4760 free_input_buffer(pmem_bufferHdr);
4761 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004762}
4763
4764OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4765{
Arun Menon906de572013-06-18 17:01:40 -07004766 unsigned int index = 0;
4767 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4768 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004769 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004770
Arun Menon906de572013-06-18 17:01:40 -07004771 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004772 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004773
4774 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004775 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004776 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4777 struct vdec_setbuffer_cmd setbuffers;
4778 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4779 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4780 sizeof (vdec_bufferpayload));
4781 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004782 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004783 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004784 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004785 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4786 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4787 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4788 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4789 }
4790 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4791 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4792 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4793 free(m_desc_buffer_ptr[index].buf_addr);
4794 m_desc_buffer_ptr[index].buf_addr = NULL;
4795 m_desc_buffer_ptr[index].desc_data_size = 0;
4796 }
4797#ifdef USE_ION
4798 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4799#endif
4800 }
4801 }
4802
4803 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004804}
4805
4806OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4807{
Arun Menon906de572013-06-18 17:01:40 -07004808 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004809
Arun Menon906de572013-06-18 17:01:40 -07004810 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4811 return OMX_ErrorBadParameter;
4812 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004813
Arun Menon906de572013-06-18 17:01:40 -07004814 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004815 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004816
Arun Menon906de572013-06-18 17:01:40 -07004817 if (index < drv_ctx.op_buf.actualcount
4818 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004819 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004820 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004821
Arun Menon906de572013-06-18 17:01:40 -07004822 struct vdec_setbuffer_cmd setbuffers;
4823 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4824 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4825 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004826
4827 if (!dynamic_buf_mode) {
Balamurugan Alagarsamye773c582014-12-17 15:10:25 +05304828 if (streaming[CAPTURE_PORT] &&
4829 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) {
4830 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
4831 DEBUG_PRINT_ERROR("STREAMOFF Failed");
4832 } else {
4833 DEBUG_PRINT_LOW("STREAMOFF Successful");
4834 }
4835 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004836#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004837 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004838 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004839 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4840 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4841 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4842 }
Arun Menon906de572013-06-18 17:01:40 -07004843 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004844 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4845 } else {
4846#endif
4847 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4848 if (!secure_mode) {
4849 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4850 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4851 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4852 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4853 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4854 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4855 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4856 }
4857 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4858 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004859#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004860 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004861#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004862 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004863#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004864 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004865#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004866 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004867 if (release_output_done()) {
4868 free_extradata();
4869 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004870 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004871
Arun Menon906de572013-06-18 17:01:40 -07004872 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004873
4874}
4875
4876OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004877 OMX_BUFFERHEADERTYPE **bufferHdr,
4878 OMX_U32 port,
4879 OMX_PTR appData,
4880 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004881{
Arun Menon906de572013-06-18 17:01:40 -07004882 OMX_BUFFERHEADERTYPE *input = NULL;
4883 unsigned char *buf_addr = NULL;
4884 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4885 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004886
Arun Menon906de572013-06-18 17:01:40 -07004887 /* Sanity Check*/
4888 if (bufferHdr == NULL) {
4889 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004890 }
4891
Arun Menon906de572013-06-18 17:01:40 -07004892 if (m_inp_heap_ptr == NULL) {
4893 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4894 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4895 drv_ctx.ip_buf.actualcount);
4896 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4897 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4898 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004899
Arun Menon8544ead2014-05-08 17:42:29 -07004900 if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
4901 DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004902 return OMX_ErrorInsufficientResources;
4903 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004904 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004905
Arun Menon906de572013-06-18 17:01:40 -07004906 /*Find a Free index*/
4907 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4908 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004909 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004910 break;
4911 }
4912 }
4913
4914 if (i < drv_ctx.ip_buf.actualcount) {
4915 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4916
4917 if (buf_addr == NULL) {
4918 return OMX_ErrorInsufficientResources;
4919 }
4920
4921 *bufferHdr = (m_inp_heap_ptr + i);
4922 input = *bufferHdr;
4923 BITMASK_SET(&m_heap_inp_bm_count,i);
4924
4925 input->pBuffer = (OMX_U8 *)buf_addr;
4926 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4927 input->nVersion.nVersion = OMX_SPEC_VERSION;
4928 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4929 input->pAppPrivate = appData;
4930 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004931 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004932 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004933 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004934 /*Add the Buffers to freeq*/
4935 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4936 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004937 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004938 return OMX_ErrorInsufficientResources;
4939 }
4940 } else {
4941 return OMX_ErrorBadParameter;
4942 }
4943
4944 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004945
4946}
4947
4948
4949/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004950 FUNCTION
4951 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004952
Arun Menon906de572013-06-18 17:01:40 -07004953 DESCRIPTION
4954 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004955
Arun Menon906de572013-06-18 17:01:40 -07004956 PARAMETERS
4957 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004958
Arun Menon906de572013-06-18 17:01:40 -07004959 RETURN VALUE
4960 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004961
Arun Menon906de572013-06-18 17:01:40 -07004962 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004963OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004964 OMX_IN OMX_HANDLETYPE hComp,
4965 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4966 OMX_IN OMX_U32 port,
4967 OMX_IN OMX_PTR appData,
4968 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004969{
4970
Arun Menon906de572013-06-18 17:01:40 -07004971 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4972 struct vdec_setbuffer_cmd setbuffers;
4973 OMX_BUFFERHEADERTYPE *input = NULL;
4974 unsigned i = 0;
4975 unsigned char *buf_addr = NULL;
4976 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004977
Arun Menon906de572013-06-18 17:01:40 -07004978 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004979 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004980 bytes, drv_ctx.ip_buf.buffer_size);
4981 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004982 }
4983
Arun Menon906de572013-06-18 17:01:40 -07004984 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004985 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004986 drv_ctx.ip_buf.actualcount,
4987 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004988
Arun Menon906de572013-06-18 17:01:40 -07004989 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4990 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4991
4992 if (m_inp_mem_ptr == NULL) {
4993 return OMX_ErrorInsufficientResources;
4994 }
4995
4996 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4997 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4998
4999 if (drv_ctx.ptr_inputbuffer == NULL) {
5000 return OMX_ErrorInsufficientResources;
5001 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005002#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005003 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
5004 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005005
Arun Menon906de572013-06-18 17:01:40 -07005006 if (drv_ctx.ip_buf_ion_info == NULL) {
5007 return OMX_ErrorInsufficientResources;
5008 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005009#endif
5010
Arun Menon906de572013-06-18 17:01:40 -07005011 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
5012 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005013#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005014 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005015#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07005016 }
5017 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005018
Arun Menon906de572013-06-18 17:01:40 -07005019 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
5020 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005021 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005022 break;
5023 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005024 }
Arun Menon906de572013-06-18 17:01:40 -07005025
5026 if (i < drv_ctx.ip_buf.actualcount) {
5027 struct v4l2_buffer buf;
5028 struct v4l2_plane plane;
5029 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005030 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07005031#ifdef USE_ION
5032 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
5033 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
5034 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
5035 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
5036 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
5037 return OMX_ErrorInsufficientResources;
5038 }
5039 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
5040#else
5041 pmem_fd = open (MEM_DEVICE,O_RDWR);
5042
5043 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005044 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005045 return OMX_ErrorInsufficientResources;
5046 }
5047
5048 if (pmem_fd == 0) {
5049 pmem_fd = open (MEM_DEVICE,O_RDWR);
5050
5051 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005052 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005053 return OMX_ErrorInsufficientResources;
5054 }
5055 }
5056
5057 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
5058 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005059 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005060 close(pmem_fd);
5061 return OMX_ErrorInsufficientResources;
5062 }
5063#endif
5064 if (!secure_mode) {
5065 buf_addr = (unsigned char *)mmap(NULL,
5066 drv_ctx.ip_buf.buffer_size,
5067 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
5068
5069 if (buf_addr == MAP_FAILED) {
5070 close(pmem_fd);
5071#ifdef USE_ION
5072 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
5073#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005074 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07005075 return OMX_ErrorInsufficientResources;
5076 }
5077 }
5078 *bufferHdr = (m_inp_mem_ptr + i);
5079 if (secure_mode)
5080 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
5081 else
5082 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
5083 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
5084 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
5085 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
5086 drv_ctx.ptr_inputbuffer [i].offset = 0;
5087
5088
5089 buf.index = i;
5090 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5091 buf.memory = V4L2_MEMORY_USERPTR;
5092 plane.bytesused = 0;
5093 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
5094 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
5095 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
5096 plane.reserved[1] = 0;
5097 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
5098 buf.m.planes = &plane;
5099 buf.length = 1;
5100
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005101 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07005102 drv_ctx.ptr_inputbuffer[i].bufferaddr);
5103
5104 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5105
5106 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005107 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07005108 /*TODO: How to handle this case */
5109 return OMX_ErrorInsufficientResources;
5110 }
5111
5112 input = *bufferHdr;
5113 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005114 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07005115 if (secure_mode)
5116 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
5117 else
5118 input->pBuffer = (OMX_U8 *)buf_addr;
5119 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5120 input->nVersion.nVersion = OMX_SPEC_VERSION;
5121 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
5122 input->pAppPrivate = appData;
5123 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
5124 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
5125
5126 if (drv_ctx.disable_dmx) {
5127 eRet = allocate_desc_buffer(i);
5128 }
5129 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005130 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07005131 eRet = OMX_ErrorInsufficientResources;
5132 }
5133 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005134}
5135
5136
5137/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005138 FUNCTION
5139 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005140
Arun Menon906de572013-06-18 17:01:40 -07005141 DESCRIPTION
5142 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07005143
Arun Menon906de572013-06-18 17:01:40 -07005144 PARAMETERS
5145 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005146
Arun Menon906de572013-06-18 17:01:40 -07005147 RETURN VALUE
5148 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005149
Arun Menon906de572013-06-18 17:01:40 -07005150 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005151OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07005152 OMX_IN OMX_HANDLETYPE hComp,
5153 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5154 OMX_IN OMX_U32 port,
5155 OMX_IN OMX_PTR appData,
5156 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005157{
Arun Menon906de572013-06-18 17:01:40 -07005158 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5159 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
5160 unsigned i= 0; // Temporary counter
5161 struct vdec_setbuffer_cmd setbuffers;
5162 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005163#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005164 int ion_device_fd =-1;
5165 struct ion_allocation_data ion_alloc_data;
5166 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005167#endif
Arun Menon906de572013-06-18 17:01:40 -07005168 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005169 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07005170 drv_ctx.op_buf.actualcount,
5171 drv_ctx.op_buf.buffer_size);
5172 int nBufHdrSize = 0;
5173 int nPlatformEntrySize = 0;
5174 int nPlatformListSize = 0;
5175 int nPMEMInfoSize = 0;
5176 int pmem_fd = -1;
5177 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005178
Arun Menon906de572013-06-18 17:01:40 -07005179 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
5180 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
5181 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005182
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005183 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07005184 drv_ctx.op_buf.actualcount);
5185 nBufHdrSize = drv_ctx.op_buf.actualcount *
5186 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005187
Arun Menon906de572013-06-18 17:01:40 -07005188 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
5189 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
5190 nPlatformListSize = drv_ctx.op_buf.actualcount *
5191 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
5192 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
5193 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005194
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005195 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07005196 sizeof(OMX_BUFFERHEADERTYPE),
5197 nPMEMInfoSize,
5198 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005199 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07005200 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005201#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005202 ion_device_fd = alloc_map_ion_memory(
5203 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
5204 drv_ctx.op_buf.alignment,
5205 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
5206 if (ion_device_fd < 0) {
5207 return OMX_ErrorInsufficientResources;
5208 }
5209 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005210#else
Arun Menon906de572013-06-18 17:01:40 -07005211 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005212
Arun Menon906de572013-06-18 17:01:40 -07005213 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005214 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005215 drv_ctx.op_buf.buffer_size);
5216 return OMX_ErrorInsufficientResources;
5217 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005218
Arun Menon906de572013-06-18 17:01:40 -07005219 if (pmem_fd == 0) {
5220 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005221
Arun Menon906de572013-06-18 17:01:40 -07005222 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005223 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07005224 drv_ctx.op_buf.buffer_size);
5225 return OMX_ErrorInsufficientResources;
5226 }
5227 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005228
Arun Menon906de572013-06-18 17:01:40 -07005229 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
5230 drv_ctx.op_buf.actualcount,
5231 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005232 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07005233 close(pmem_fd);
5234 return OMX_ErrorInsufficientResources;
5235 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005236#endif
Arun Menon906de572013-06-18 17:01:40 -07005237 if (!secure_mode) {
5238 pmem_baseaddress = (unsigned char *)mmap(NULL,
5239 (drv_ctx.op_buf.buffer_size *
5240 drv_ctx.op_buf.actualcount),
5241 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
5242 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005243 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07005244 drv_ctx.op_buf.buffer_size);
5245 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005246#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005247 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005248#endif
Arun Menon906de572013-06-18 17:01:40 -07005249 return OMX_ErrorInsufficientResources;
5250 }
5251 }
5252 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5253 // Alloc mem for platform specific info
5254 char *pPtr=NULL;
5255 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5256 nPMEMInfoSize,1);
5257 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5258 calloc (sizeof(struct vdec_bufferpayload),
5259 drv_ctx.op_buf.actualcount);
5260 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5261 calloc (sizeof (struct vdec_output_frameinfo),
5262 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005263 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
5264 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
5265 return OMX_ErrorInsufficientResources;
5266 }
5267
Arun Menon906de572013-06-18 17:01:40 -07005268#ifdef USE_ION
5269 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5270 calloc (sizeof(struct vdec_ion),
5271 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07005272 if (!drv_ctx.op_buf_ion_info) {
5273 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
5274 return OMX_ErrorInsufficientResources;
5275 }
Arun Menon906de572013-06-18 17:01:40 -07005276#endif
5277
5278 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5279 && drv_ctx.ptr_respbuffer) {
5280 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5281 (drv_ctx.op_buf.buffer_size *
5282 drv_ctx.op_buf.actualcount);
5283 bufHdr = m_out_mem_ptr;
5284 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5285 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5286 (((char *) m_platform_list) + nPlatformListSize);
5287 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5288 (((char *) m_platform_entry) + nPlatformEntrySize);
5289 pPlatformList = m_platform_list;
5290 pPlatformEntry = m_platform_entry;
5291 pPMEMInfo = m_pmem_info;
5292
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005293 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07005294
5295 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005296 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
5297 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07005298 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
5299 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5300 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5301 // Set the values when we determine the right HxW param
5302 bufHdr->nAllocLen = bytes;
5303 bufHdr->nFilledLen = 0;
5304 bufHdr->pAppPrivate = appData;
5305 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5306 // Platform specific PMEM Information
5307 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005308 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005309 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5310 pPlatformEntry->entry = pPMEMInfo;
5311 // Initialize the Platform List
5312 pPlatformList->nEntries = 1;
5313 pPlatformList->entryList = pPlatformEntry;
5314 // Keep pBuffer NULL till vdec is opened
5315 bufHdr->pBuffer = NULL;
5316 bufHdr->nOffset = 0;
5317
5318 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5319 pPMEMInfo->pmem_fd = 0;
5320 bufHdr->pPlatformPrivate = pPlatformList;
5321
5322 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5323 m_pmem_info[i].pmem_fd = pmem_fd;
5324#ifdef USE_ION
5325 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5326 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5327 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5328#endif
5329
5330 /*Create a mapping between buffers*/
5331 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5332 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5333 &drv_ctx.ptr_outputbuffer[i];
5334 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5335 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5336 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305337 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5338 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5339 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005340
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005341 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005342 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5343 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5344 // Move the buffer and buffer header pointers
5345 bufHdr++;
5346 pPMEMInfo++;
5347 pPlatformEntry++;
5348 pPlatformList++;
5349 }
5350 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005351 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005352 m_out_mem_ptr, pPtr);
5353 if (m_out_mem_ptr) {
5354 free(m_out_mem_ptr);
5355 m_out_mem_ptr = NULL;
5356 }
5357 if (pPtr) {
5358 free(pPtr);
5359 pPtr = NULL;
5360 }
5361 if (drv_ctx.ptr_outputbuffer) {
5362 free(drv_ctx.ptr_outputbuffer);
5363 drv_ctx.ptr_outputbuffer = NULL;
5364 }
5365 if (drv_ctx.ptr_respbuffer) {
5366 free(drv_ctx.ptr_respbuffer);
5367 drv_ctx.ptr_respbuffer = NULL;
5368 }
5369#ifdef USE_ION
5370 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005371 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005372 free(drv_ctx.op_buf_ion_info);
5373 drv_ctx.op_buf_ion_info = NULL;
5374 }
5375#endif
5376 eRet = OMX_ErrorInsufficientResources;
5377 }
5378 if (eRet == OMX_ErrorNone)
5379 eRet = allocate_extradata();
5380 }
5381
5382 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5383 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005384 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005385 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005386 }
5387 }
Arun Menon906de572013-06-18 17:01:40 -07005388
5389 if (eRet == OMX_ErrorNone) {
5390 if (i < drv_ctx.op_buf.actualcount) {
5391 struct v4l2_buffer buf;
5392 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5393 int rc;
5394 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5395
5396 drv_ctx.ptr_outputbuffer[i].buffer_len =
5397 drv_ctx.op_buf.buffer_size;
5398
5399 *bufferHdr = (m_out_mem_ptr + i );
5400 if (secure_mode) {
5401 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5402 }
5403 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5404
5405 buf.index = i;
5406 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5407 buf.memory = V4L2_MEMORY_USERPTR;
5408 plane[0].length = drv_ctx.op_buf.buffer_size;
5409 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5410 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005411#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005412 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005413#endif
Arun Menon906de572013-06-18 17:01:40 -07005414 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5415 plane[0].data_offset = 0;
5416 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5417 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5418 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5419 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 -07005420#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005421 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005422#endif
Arun Menon906de572013-06-18 17:01:40 -07005423 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5424 plane[extra_idx].data_offset = 0;
5425 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005426 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005427 return OMX_ErrorBadParameter;
5428 }
5429 buf.m.planes = plane;
5430 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005431 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 -07005432 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5433 if (rc) {
5434 /*TODO: How to handle this case */
5435 return OMX_ErrorInsufficientResources;
5436 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005437
Arun Menon906de572013-06-18 17:01:40 -07005438 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5439 enum v4l2_buf_type buf_type;
5440 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5441 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5442 if (rc) {
5443 return OMX_ErrorInsufficientResources;
5444 } else {
5445 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005446 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005447 }
5448 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005449
Arun Menon906de572013-06-18 17:01:40 -07005450 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5451 (*bufferHdr)->pAppPrivate = appData;
5452 BITMASK_SET(&m_out_bm_count,i);
5453 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005454 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005455 eRet = OMX_ErrorInsufficientResources;
5456 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005457 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005458
Arun Menon906de572013-06-18 17:01:40 -07005459 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005460}
5461
5462
5463// AllocateBuffer -- API Call
5464/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005465 FUNCTION
5466 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005467
Arun Menon906de572013-06-18 17:01:40 -07005468 DESCRIPTION
5469 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005470
Arun Menon906de572013-06-18 17:01:40 -07005471 PARAMETERS
5472 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005473
Arun Menon906de572013-06-18 17:01:40 -07005474 RETURN VALUE
5475 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005476
Arun Menon906de572013-06-18 17:01:40 -07005477 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005478OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005479 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5480 OMX_IN OMX_U32 port,
5481 OMX_IN OMX_PTR appData,
5482 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005483{
5484 unsigned i = 0;
5485 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5486
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005487 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005488 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005489 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005490 return OMX_ErrorInvalidState;
5491 }
5492
Arun Menon906de572013-06-18 17:01:40 -07005493 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5494 if (arbitrary_bytes) {
5495 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5496 } else {
5497 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5498 }
5499 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005500 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5501 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005502 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005503 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005504 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005505 }
5506 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005507 if (eRet == OMX_ErrorNone) {
5508 if (allocate_done()) {
5509 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005510 // Send the callback now
5511 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5512 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005513 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005514 }
5515 }
Arun Menon906de572013-06-18 17:01:40 -07005516 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5517 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5518 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5519 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005520 OMX_CORE_INPUT_PORT_INDEX,
5521 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005522 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005523 }
Arun Menon906de572013-06-18 17:01:40 -07005524 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5525 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5526 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005527 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005528 OMX_CORE_OUTPUT_PORT_INDEX,
5529 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005530 }
5531 }
5532 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005533 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005534 return eRet;
5535}
5536
5537// Free Buffer - API call
5538/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005539 FUNCTION
5540 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005541
Arun Menon906de572013-06-18 17:01:40 -07005542 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005543
Arun Menon906de572013-06-18 17:01:40 -07005544 PARAMETERS
5545 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005546
Arun Menon906de572013-06-18 17:01:40 -07005547 RETURN VALUE
5548 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005549
Arun Menon906de572013-06-18 17:01:40 -07005550 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005551OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005552 OMX_IN OMX_U32 port,
5553 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005554{
5555 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5556 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005557 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005558
Arun Menon906de572013-06-18 17:01:40 -07005559 if (m_state == OMX_StateIdle &&
5560 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005561 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005562 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5563 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005564 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005565 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5566 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5567 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5568 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005569 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005570 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005571 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005572 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005573 OMX_ErrorPortUnpopulated,
5574 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005575
5576 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005577 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005578 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005579 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005580 OMX_ErrorPortUnpopulated,
5581 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005582 }
5583
Arun Menon906de572013-06-18 17:01:40 -07005584 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5585 /*Check if arbitrary bytes*/
5586 if (!arbitrary_bytes && !input_use_buffer)
5587 nPortIndex = buffer - m_inp_mem_ptr;
5588 else
5589 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005590
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005591 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005592 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5593 // Clear the bit associated with it.
5594 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5595 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5596 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005597
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005598 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005599 if (m_phdr_pmem_ptr)
5600 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5601 } else {
5602 if (arbitrary_bytes) {
5603 if (m_phdr_pmem_ptr)
5604 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5605 else
5606 free_input_buffer(nPortIndex,NULL);
5607 } else
5608 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005609 }
Arun Menon906de572013-06-18 17:01:40 -07005610 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305611 if(release_input_done())
5612 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005613 /*Free the Buffer Header*/
5614 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005615 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005616 free_input_buffer_header();
5617 }
5618 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005619 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005620 eRet = OMX_ErrorBadPortIndex;
5621 }
5622
Arun Menon906de572013-06-18 17:01:40 -07005623 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5624 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005625 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005626 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5627 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005628 OMX_CORE_INPUT_PORT_INDEX,
5629 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005630 }
Arun Menon906de572013-06-18 17:01:40 -07005631 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005632 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005633 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005634 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005635 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005636 // Clear the bit associated with it.
5637 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5638 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005639 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005640
Surajit Podder12aefac2013-08-06 18:43:32 +05305641 if(release_output_done()) {
5642 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5643 }
Arun Menon906de572013-06-18 17:01:40 -07005644 if (release_output_done()) {
5645 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005646 }
Arun Menon906de572013-06-18 17:01:40 -07005647 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005648 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005649 eRet = OMX_ErrorBadPortIndex;
5650 }
Arun Menon906de572013-06-18 17:01:40 -07005651 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5652 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005653 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005654
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005655 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005656 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005657#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005658 if (m_enable_android_native_buffers) {
5659 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5660 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5661 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005662#endif
5663
Arun Menon906de572013-06-18 17:01:40 -07005664 post_event(OMX_CommandPortDisable,
5665 OMX_CORE_OUTPUT_PORT_INDEX,
5666 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005667 }
Arun Menon906de572013-06-18 17:01:40 -07005668 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005669 eRet = OMX_ErrorBadPortIndex;
5670 }
Arun Menon906de572013-06-18 17:01:40 -07005671 if ((eRet == OMX_ErrorNone) &&
5672 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5673 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005674 // Send the callback now
5675 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5676 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005677 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005678 }
5679 }
5680 return eRet;
5681}
5682
5683
5684/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005685 FUNCTION
5686 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005687
Arun Menon906de572013-06-18 17:01:40 -07005688 DESCRIPTION
5689 This routine is used to push the encoded video frames to
5690 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005691
Arun Menon906de572013-06-18 17:01:40 -07005692 PARAMETERS
5693 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005694
Arun Menon906de572013-06-18 17:01:40 -07005695 RETURN VALUE
5696 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005697
Arun Menon906de572013-06-18 17:01:40 -07005698 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005699OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005700 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005701{
Arun Menon906de572013-06-18 17:01:40 -07005702 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5703 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005704
Arun Menon906de572013-06-18 17:01:40 -07005705 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005706 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005707 return OMX_ErrorInvalidState;
5708 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005709
Arun Menon906de572013-06-18 17:01:40 -07005710 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005711 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005712 return OMX_ErrorBadParameter;
5713 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005714
Arun Menon906de572013-06-18 17:01:40 -07005715 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005716 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005717 return OMX_ErrorIncorrectStateOperation;
5718 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005719
Arun Menon906de572013-06-18 17:01:40 -07005720 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005721 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005722 return OMX_ErrorBadPortIndex;
5723 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005724
5725#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005726 if (iDivXDrmDecrypt) {
5727 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5728 if (drmErr != OMX_ErrorNone) {
5729 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005730 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005731 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005732 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005733#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005734 if (perf_flag) {
5735 if (!latency) {
5736 dec_time.stop();
5737 latency = dec_time.processing_time_us();
5738 dec_time.start();
5739 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005740 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005741
Arun Menon906de572013-06-18 17:01:40 -07005742 if (arbitrary_bytes) {
5743 nBufferIndex = buffer - m_inp_heap_ptr;
5744 } else {
5745 if (input_use_buffer == true) {
5746 nBufferIndex = buffer - m_inp_heap_ptr;
5747 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5748 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5749 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5750 buffer = &m_inp_mem_ptr[nBufferIndex];
5751 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5752 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5753 } else {
5754 nBufferIndex = buffer - m_inp_mem_ptr;
5755 }
5756 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005757
Arun Menon906de572013-06-18 17:01:40 -07005758 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005759 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005760 return OMX_ErrorBadParameter;
5761 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005762
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005763 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5764 codec_config_flag = true;
5765 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5766 }
5767
Arun Menon906de572013-06-18 17:01:40 -07005768 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5769 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5770 if (arbitrary_bytes) {
5771 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005772 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005773 } else {
Arun Menon906de572013-06-18 17:01:40 -07005774 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5775 }
Praveen Chavanece713f2014-12-10 18:00:04 -08005776 time_stamp_dts.insert_timestamp(buffer);
Arun Menon906de572013-06-18 17:01:40 -07005777 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005778}
5779
5780/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005781 FUNCTION
5782 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005783
Arun Menon906de572013-06-18 17:01:40 -07005784 DESCRIPTION
5785 This routine is used to push the encoded video frames to
5786 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005787
Arun Menon906de572013-06-18 17:01:40 -07005788 PARAMETERS
5789 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005790
Arun Menon906de572013-06-18 17:01:40 -07005791 RETURN VALUE
5792 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005793
Arun Menon906de572013-06-18 17:01:40 -07005794 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005795OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005796 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005797{
Arun Menon906de572013-06-18 17:01:40 -07005798 int push_cnt = 0,i=0;
5799 unsigned nPortIndex = 0;
5800 OMX_ERRORTYPE ret = OMX_ErrorNone;
5801 struct vdec_input_frameinfo frameinfo;
5802 struct vdec_bufferpayload *temp_buffer;
5803 struct vdec_seqheader seq_header;
5804 bool port_setting_changed = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005805
Arun Menon906de572013-06-18 17:01:40 -07005806 /*Should we generate a Aync error event*/
5807 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005808 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005809 return OMX_ErrorBadParameter;
5810 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005811
Arun Menon906de572013-06-18 17:01:40 -07005812 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005813
Arun Menon906de572013-06-18 17:01:40 -07005814 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005815 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005816 nPortIndex);
5817 return OMX_ErrorBadParameter;
5818 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005819
Arun Menon906de572013-06-18 17:01:40 -07005820 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005821
Arun Menon906de572013-06-18 17:01:40 -07005822 /* return zero length and not an EOS buffer */
5823 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5824 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005825 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005826 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5827 OMX_COMPONENT_GENERATE_EBD);
5828 return OMX_ErrorNone;
5829 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005830
c_sridur0af9cef2015-02-05 12:07:17 +05305831 if (input_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005832 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005833 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5834 OMX_COMPONENT_GENERATE_EBD);
5835 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005836 }
5837
Arun Menon906de572013-06-18 17:01:40 -07005838 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005839
Surajit Podderd2644d52013-08-28 17:59:06 +05305840 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005841 return OMX_ErrorBadParameter;
5842 }
5843 /* If its first frame, H264 codec and reject is true, then parse the nal
5844 and get the profile. Based on this, reject the clip playback */
5845 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5846 m_reject_avc_1080p_mp) {
5847 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005848 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005849 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5850 NALU_TYPE_SPS);
5851 m_profile = h264_parser->get_profile();
5852 ret = is_video_session_supported();
5853 if (ret) {
5854 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5855 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5856 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5857 m_state = OMX_StateInvalid;
5858 return OMX_ErrorNone;
5859 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005860 }
5861
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005862 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005863 /*for use buffer we need to memcpy the data*/
5864 temp_buffer->buffer_len = buffer->nFilledLen;
5865
5866 if (input_use_buffer) {
5867 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5868 if (arbitrary_bytes) {
5869 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5870 } else {
5871 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5872 buffer->nFilledLen);
5873 }
5874 } else {
5875 return OMX_ErrorBadParameter;
5876 }
5877
5878 }
5879
5880 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5881 frameinfo.client_data = (void *) buffer;
5882 frameinfo.datalen = temp_buffer->buffer_len;
5883 frameinfo.flags = 0;
5884 frameinfo.offset = buffer->nOffset;
5885 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5886 frameinfo.pmem_offset = temp_buffer->offset;
5887 frameinfo.timestamp = buffer->nTimeStamp;
5888 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5889 DEBUG_PRINT_LOW("ETB: dmx enabled");
5890 if (m_demux_entries == 0) {
5891 extract_demux_addr_offsets(buffer);
5892 }
5893
5894 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5895 handle_demux_data(buffer);
5896 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5897 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5898 } else {
5899 frameinfo.desc_addr = NULL;
5900 frameinfo.desc_size = 0;
5901 }
5902 if (!arbitrary_bytes) {
5903 frameinfo.flags |= buffer->nFlags;
5904 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005905
5906#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005907 if (m_debug_timestamp) {
5908 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005909 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005910 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5911 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005912 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005913 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5914 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005915 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005916#endif
5917
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005918log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005919
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005920if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005921 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5922 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5923 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005924
Arun Menon906de572013-06-18 17:01:40 -07005925 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005926 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005927 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5928 h264_scratch.nFilledLen = 0;
5929 nal_count = 0;
5930 look_ahead_nal = false;
5931 frame_count = 0;
5932 if (m_frame_parser.mutils)
5933 m_frame_parser.mutils->initialize_frame_checking_environment();
5934 m_frame_parser.flush();
5935 h264_last_au_ts = LLONG_MAX;
5936 h264_last_au_flags = 0;
5937 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5938 m_demux_entries = 0;
5939 }
5940 struct v4l2_buffer buf;
5941 struct v4l2_plane plane;
5942 memset( (void *)&buf, 0, sizeof(buf));
5943 memset( (void *)&plane, 0, sizeof(plane));
5944 int rc;
5945 unsigned long print_count;
5946 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005947 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005948 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005949 }
5950 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5951 buf.index = nPortIndex;
5952 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5953 buf.memory = V4L2_MEMORY_USERPTR;
5954 plane.bytesused = temp_buffer->buffer_len;
5955 plane.length = drv_ctx.ip_buf.buffer_size;
5956 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5957 (unsigned long)temp_buffer->offset;
5958 plane.reserved[0] = temp_buffer->pmem_fd;
5959 plane.reserved[1] = temp_buffer->offset;
5960 plane.data_offset = 0;
5961 buf.m.planes = &plane;
5962 buf.length = 1;
5963 if (frameinfo.timestamp >= LLONG_MAX) {
5964 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5965 }
5966 //assumption is that timestamp is in milliseconds
5967 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5968 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5969 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5970 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005971
Pushkaraj Patil20bd6bf2014-12-22 19:33:08 +05305972 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5973 DEBUG_PRINT_LOW("Increment codec_config buffer counter");
5974 android_atomic_inc(&m_queued_codec_config_count);
5975 }
5976
Arun Menon906de572013-06-18 17:01:40 -07005977 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5978 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005979 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005980 return OMX_ErrorHardware;
5981 }
Deva Ramasubramanian1fd93812014-03-26 15:17:15 -07005982
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005983 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5984 codec_config_flag = false;
5985 }
Arun Menon906de572013-06-18 17:01:40 -07005986 if (!streaming[OUTPUT_PORT]) {
5987 enum v4l2_buf_type buf_type;
5988 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005989
Arun Menon906de572013-06-18 17:01:40 -07005990 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005991 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005992 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5993 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005994 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005995 streaming[OUTPUT_PORT] = true;
Jia Meng1e236c82014-04-03 10:54:39 +08005996 } else if (errno == EBUSY) {
5997 DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
5998 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
5999 OMX_COMPONENT_GENERATE_EBD);
6000 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006001 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006002 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07006003 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
Jia Meng1e236c82014-04-03 10:54:39 +08006004 post_event ((unsigned int)buffer, VDEC_S_SUCCESS,
Arun Menon906de572013-06-18 17:01:40 -07006005 OMX_COMPONENT_GENERATE_EBD);
6006 return OMX_ErrorBadParameter;
6007 }
6008 }
6009 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
6010 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006011
Arun Menon906de572013-06-18 17:01:40 -07006012 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006013}
6014
6015/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006016 FUNCTION
6017 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07006018
Arun Menon906de572013-06-18 17:01:40 -07006019 DESCRIPTION
6020 IL client uses this method to release the frame buffer
6021 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006022
Arun Menon906de572013-06-18 17:01:40 -07006023 PARAMETERS
6024 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006025
Arun Menon906de572013-06-18 17:01:40 -07006026 RETURN VALUE
6027 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006028
Arun Menon906de572013-06-18 17:01:40 -07006029 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006030OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006031 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006032{
Jia Meng2d51b932014-07-10 14:02:54 +08006033 unsigned nPortIndex = 0;
Arun Menonbdb80b02013-08-12 17:45:54 -07006034 if (dynamic_buf_mode) {
6035 private_handle_t *handle = NULL;
6036 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07006037 unsigned int nPortIndex = 0;
6038
6039 if (!buffer || !buffer->pBuffer) {
Arun Menon8544ead2014-05-08 17:42:29 -07006040 DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
Arun Menonbdb80b02013-08-12 17:45:54 -07006041 return OMX_ErrorBadParameter;
6042 }
6043
6044 //get the buffer type and fd info
6045 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
6046 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08006047 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
6048
6049 if (!handle) {
6050 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
6051 return OMX_ErrorBadParameter;
6052 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006053 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
6054 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6055 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08006056 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006057
6058 //Store private handle from GraphicBuffer
6059 native_buffer[nPortIndex].privatehandle = handle;
6060 native_buffer[nPortIndex].nativehandle = handle;
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006061
6062 //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
6063 //this with a more sane size so that we don't compensate in rest of code
6064 //We'll restore this size later on, so that it's transparent to client
6065 buffer->nFilledLen = 0;
Deva Ramasubramanian03a5bb92014-04-25 19:03:50 -07006066 buffer->nAllocLen = handle->size;
Arun Menonbdb80b02013-08-12 17:45:54 -07006067 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006068
Arun Menon906de572013-06-18 17:01:40 -07006069 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006070 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07006071 return OMX_ErrorInvalidState;
6072 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006073
Arun Menon906de572013-06-18 17:01:40 -07006074 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006075 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07006076 return OMX_ErrorIncorrectStateOperation;
6077 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006078
Jia Meng2d51b932014-07-10 14:02:54 +08006079 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07006080 if (buffer == NULL ||
Jia Meng2d51b932014-07-10 14:02:54 +08006081 (nPortIndex >= drv_ctx.op_buf.actualcount)) {
6082 DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
6083 nPortIndex, drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07006084 return OMX_ErrorBadParameter;
6085 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006086
Arun Menon906de572013-06-18 17:01:40 -07006087 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006088 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07006089 return OMX_ErrorBadPortIndex;
6090 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006091
Arun Menon906de572013-06-18 17:01:40 -07006092 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6093 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
6094 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006095}
6096/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006097 FUNCTION
6098 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07006099
Arun Menon906de572013-06-18 17:01:40 -07006100 DESCRIPTION
6101 IL client uses this method to release the frame buffer
6102 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006103
Arun Menon906de572013-06-18 17:01:40 -07006104 PARAMETERS
6105 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006106
Arun Menon906de572013-06-18 17:01:40 -07006107 RETURN VALUE
6108 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006109
Arun Menon906de572013-06-18 17:01:40 -07006110 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006111OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07006112 OMX_IN OMX_HANDLETYPE hComp,
6113 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006114{
Arun Menon906de572013-06-18 17:01:40 -07006115 OMX_ERRORTYPE nRet = OMX_ErrorNone;
6116 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
6117 unsigned nPortIndex = 0;
6118 struct vdec_fillbuffer_cmd fillbuffer;
6119 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
6120 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006121
Arun Menon906de572013-06-18 17:01:40 -07006122 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07006123
Jia Meng2d51b932014-07-10 14:02:54 +08006124 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) {
6125 DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
6126 nPortIndex, drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07006127 return OMX_ErrorBadParameter;
Jia Meng2d51b932014-07-10 14:02:54 +08006128 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006129
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006130 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006131 bufferAdd, bufferAdd->pBuffer);
6132 /*Return back the output buffer to client*/
6133 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006134 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07006135 buffer->nFilledLen = 0;
6136 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6137 return OMX_ErrorNone;
6138 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08006139
6140 if (dynamic_buf_mode) {
6141 //map the buffer handle based on the size set on output port definition.
6142 if (!secure_mode) {
6143 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
6144 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
6145 PROT_READ|PROT_WRITE, MAP_SHARED,
6146 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
6147 }
6148 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
6149 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
6150 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
6151 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
6152 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
6153 }
6154
Arun Menon906de572013-06-18 17:01:40 -07006155 pending_output_buffers++;
6156 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
6157 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
6158 if (ptr_respbuffer) {
6159 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
6160 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006161
Arun Menon906de572013-06-18 17:01:40 -07006162 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
6163 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
6164 buffer->nFilledLen = 0;
6165 m_cb.FillBufferDone (hComp,m_app_data,buffer);
6166 pending_output_buffers--;
6167 return OMX_ErrorBadParameter;
6168 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006169
Arun Menon906de572013-06-18 17:01:40 -07006170 int rc = 0;
6171 struct v4l2_buffer buf;
6172 struct v4l2_plane plane[VIDEO_MAX_PLANES];
6173 memset( (void *)&buf, 0, sizeof(buf));
6174 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Arun Menon8544ead2014-05-08 17:42:29 -07006175 unsigned int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006176
Arun Menon906de572013-06-18 17:01:40 -07006177 buf.index = nPortIndex;
6178 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
6179 buf.memory = V4L2_MEMORY_USERPTR;
6180 plane[0].bytesused = buffer->nFilledLen;
6181 plane[0].length = drv_ctx.op_buf.buffer_size;
6182 plane[0].m.userptr =
6183 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
6184 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6185 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
6186 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
6187 plane[0].data_offset = 0;
6188 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
6189 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
6190 plane[extra_idx].bytesused = 0;
6191 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
6192 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 -07006193#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07006194 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006195#endif
Arun Menon906de572013-06-18 17:01:40 -07006196 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
6197 plane[extra_idx].data_offset = 0;
6198 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Arun Menon8544ead2014-05-08 17:42:29 -07006199 DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07006200 return OMX_ErrorBadParameter;
6201 }
6202 buf.m.planes = plane;
6203 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006204 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07006205 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
6206
Arun Menon906de572013-06-18 17:01:40 -07006207 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
6208 if (rc) {
6209 /*TODO: How to handle this case */
6210 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
6211 }
Arun Menon906de572013-06-18 17:01:40 -07006212return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006213}
6214
6215/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006216 FUNCTION
6217 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07006218
Arun Menon906de572013-06-18 17:01:40 -07006219 DESCRIPTION
6220 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006221
Arun Menon906de572013-06-18 17:01:40 -07006222 PARAMETERS
6223 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006224
Arun Menon906de572013-06-18 17:01:40 -07006225 RETURN VALUE
6226 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006227
Arun Menon906de572013-06-18 17:01:40 -07006228 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006229OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006230 OMX_IN OMX_CALLBACKTYPE* callbacks,
6231 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006232{
6233
Arun Menon906de572013-06-18 17:01:40 -07006234 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006235 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07006236 m_cb.EventHandler,m_cb.FillBufferDone);
6237 m_app_data = appData;
6238 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006239}
6240
6241/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006242 FUNCTION
6243 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07006244
Arun Menon906de572013-06-18 17:01:40 -07006245 DESCRIPTION
6246 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006247
Arun Menon906de572013-06-18 17:01:40 -07006248 PARAMETERS
6249 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006250
Arun Menon906de572013-06-18 17:01:40 -07006251 RETURN VALUE
6252 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006253
Arun Menon906de572013-06-18 17:01:40 -07006254 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006255OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6256{
6257#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006258 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006259 delete iDivXDrmDecrypt;
6260 iDivXDrmDecrypt=NULL;
6261 }
6262#endif //_ANDROID_
6263
Shalaj Jain286b0062013-02-21 20:35:48 -08006264 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07006265 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006266 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07006267 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006268 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07006269 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006270 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006271 }
6272
6273 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006274 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006275 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07006276 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
6277 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006278 }
6279#ifdef _ANDROID_ICS_
6280 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6281#endif
6282 }
6283
6284 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07006285 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006286 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07006287 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
6288 if (m_inp_mem_ptr)
6289 free_input_buffer (i,&m_inp_mem_ptr[i]);
6290 else
6291 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006292 }
6293 }
6294 free_input_buffer_header();
6295 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07006296 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006297 free(h264_scratch.pBuffer);
6298 h264_scratch.pBuffer = NULL;
6299 }
6300
Arun Menon906de572013-06-18 17:01:40 -07006301 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006302 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07006303 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006304 }
6305
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006306 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006307 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006308 delete (m_frame_parser.mutils);
6309 m_frame_parser.mutils = NULL;
6310 }
6311
Arun Menon906de572013-06-18 17:01:40 -07006312 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006313 free(m_platform_list);
6314 m_platform_list = NULL;
6315 }
Arun Menon906de572013-06-18 17:01:40 -07006316 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006317 free(m_vendor_config.pData);
6318 m_vendor_config.pData = NULL;
6319 }
6320
6321 // Reset counters in mesg queues
6322 m_ftb_q.m_size=0;
6323 m_cmd_q.m_size=0;
6324 m_etb_q.m_size=0;
6325 m_ftb_q.m_read = m_ftb_q.m_write =0;
6326 m_cmd_q.m_read = m_cmd_q.m_write =0;
6327 m_etb_q.m_read = m_etb_q.m_write =0;
6328#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006329 if (m_debug_timestamp) {
6330 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006331 }
6332#endif
6333
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006334 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006335 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006336 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006337 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006338
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006339 if (m_debug.infile) {
6340 fclose(m_debug.infile);
6341 m_debug.infile = NULL;
6342 }
6343 if (m_debug.outfile) {
6344 fclose(m_debug.outfile);
6345 m_debug.outfile = NULL;
6346 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006347#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006348 if (outputExtradataFile)
6349 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006350#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006351 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006352 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006353}
6354
6355/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006356 FUNCTION
6357 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006358
Arun Menon906de572013-06-18 17:01:40 -07006359 DESCRIPTION
6360 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006361
Arun Menon906de572013-06-18 17:01:40 -07006362 PARAMETERS
6363 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006364
Arun Menon906de572013-06-18 17:01:40 -07006365 RETURN VALUE
6366 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006367
Arun Menon906de572013-06-18 17:01:40 -07006368 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006369OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006370 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6371 OMX_IN OMX_U32 port,
6372 OMX_IN OMX_PTR appData,
6373 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006374{
Arun Menon906de572013-06-18 17:01:40 -07006375 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6376 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6377 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006378
6379#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006380 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6381 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006382#else
Arun Menon906de572013-06-18 17:01:40 -07006383 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006384#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006385 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006386 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006387 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006388 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006389#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006390 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006391 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006392 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006393 }
6394 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6395 eglGetProcAddress("eglQueryImageKHR");
6396 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6397 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6398 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006399#else //with OMX test app
6400 struct temp_egl {
6401 int pmem_fd;
6402 int offset;
6403 };
6404 struct temp_egl *temp_egl_id = NULL;
6405 void * pmemPtr = (void *) eglImage;
6406 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006407 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006408 fd = temp_egl_id->pmem_fd;
6409 offset = temp_egl_id->offset;
6410 }
6411#endif
6412 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006413 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006414 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006415 }
6416 pmem_info.pmem_fd = (OMX_U32) fd;
6417 pmem_info.offset = (OMX_U32) offset;
6418 pmem_entry.entry = (void *) &pmem_info;
6419 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6420 pmem_list.entryList = &pmem_entry;
6421 pmem_list.nEntries = 1;
6422 ouput_egl_buffers = true;
6423 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6424 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6425 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006426 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006427 return OMX_ErrorInsufficientResources;
6428 }
6429 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006430}
6431
6432/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006433 FUNCTION
6434 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006435
Arun Menon906de572013-06-18 17:01:40 -07006436 DESCRIPTION
6437 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006438
Arun Menon906de572013-06-18 17:01:40 -07006439 PARAMETERS
6440 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006441
Arun Menon906de572013-06-18 17:01:40 -07006442 RETURN VALUE
6443 OMX Error None if everything is successful.
6444 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006445OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006446 OMX_OUT OMX_U8* role,
6447 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006448{
Arun Menon906de572013-06-18 17:01:40 -07006449 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006450
Arun Menon906de572013-06-18 17:01:40 -07006451 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6452 if ((0 == index) && role) {
6453 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006454 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006455 } else {
6456 eRet = OMX_ErrorNoMore;
6457 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006458 }
Arun Menon906de572013-06-18 17:01:40 -07006459 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6460 if ((0 == index) && role) {
6461 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006462 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006463 } else {
6464 eRet = OMX_ErrorNoMore;
6465 }
6466 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6467 if ((0 == index) && role) {
6468 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006469 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006470 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006471 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006472 eRet = OMX_ErrorNoMore;
6473 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006474 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006475
Arun Menon906de572013-06-18 17:01:40 -07006476 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6477 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6478 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006479
Shalaj Jain273b3e02012-06-22 19:08:03 -07006480 {
Arun Menon906de572013-06-18 17:01:40 -07006481 if ((0 == index) && role) {
6482 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006483 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006484 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006485 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006486 eRet = OMX_ErrorNoMore;
6487 }
6488 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6489 if ((0 == index) && role) {
6490 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006491 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006492 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006493 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006494 eRet = OMX_ErrorNoMore;
6495 }
6496 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6497 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6498 ) {
6499 if ((0 == index) && role) {
6500 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006501 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006502 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006503 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006504 eRet = OMX_ErrorNoMore;
6505 }
6506 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6507 if ((0 == index) && role) {
6508 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006509 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006510 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006511 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006512 eRet = OMX_ErrorNoMore;
6513 }
6514 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006515 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006516 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006517 }
Arun Menon906de572013-06-18 17:01:40 -07006518 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006519}
6520
6521
6522
6523
6524/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006525 FUNCTION
6526 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006527
Arun Menon906de572013-06-18 17:01:40 -07006528 DESCRIPTION
6529 Checks if entire buffer pool is allocated by IL Client or not.
6530 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006531
Arun Menon906de572013-06-18 17:01:40 -07006532 PARAMETERS
6533 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006534
Arun Menon906de572013-06-18 17:01:40 -07006535 RETURN VALUE
6536 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006537
Arun Menon906de572013-06-18 17:01:40 -07006538 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006539bool omx_vdec::allocate_done(void)
6540{
Arun Menon906de572013-06-18 17:01:40 -07006541 bool bRet = false;
6542 bool bRet_In = false;
6543 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006544
Arun Menon906de572013-06-18 17:01:40 -07006545 bRet_In = allocate_input_done();
6546 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006547
Arun Menon906de572013-06-18 17:01:40 -07006548 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006549 bRet = true;
6550 }
Arun Menon906de572013-06-18 17:01:40 -07006551
6552 return bRet;
6553}
6554/* ======================================================================
6555 FUNCTION
6556 omx_vdec::AllocateInputDone
6557
6558 DESCRIPTION
6559 Checks if I/P buffer pool is allocated by IL Client or not.
6560
6561 PARAMETERS
6562 None.
6563
6564 RETURN VALUE
6565 true/false.
6566
6567 ========================================================================== */
6568bool omx_vdec::allocate_input_done(void)
6569{
6570 bool bRet = false;
6571 unsigned i=0;
6572
6573 if (m_inp_mem_ptr == NULL) {
6574 return bRet;
6575 }
6576 if (m_inp_mem_ptr ) {
6577 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6578 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6579 break;
6580 }
6581 }
6582 }
6583 if (i == drv_ctx.ip_buf.actualcount) {
6584 bRet = true;
6585 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6586 }
6587 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6588 m_inp_bPopulated = OMX_TRUE;
6589 }
6590 return bRet;
6591}
6592/* ======================================================================
6593 FUNCTION
6594 omx_vdec::AllocateOutputDone
6595
6596 DESCRIPTION
6597 Checks if entire O/P buffer pool is allocated by IL Client or not.
6598
6599 PARAMETERS
6600 None.
6601
6602 RETURN VALUE
6603 true/false.
6604
6605 ========================================================================== */
6606bool omx_vdec::allocate_output_done(void)
6607{
6608 bool bRet = false;
6609 unsigned j=0;
6610
6611 if (m_out_mem_ptr == NULL) {
6612 return bRet;
6613 }
6614
6615 if (m_out_mem_ptr) {
6616 for (; j < drv_ctx.op_buf.actualcount; j++) {
6617 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6618 break;
6619 }
6620 }
6621 }
6622
6623 if (j == drv_ctx.op_buf.actualcount) {
6624 bRet = true;
6625 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6626 if (m_out_bEnabled)
6627 m_out_bPopulated = OMX_TRUE;
6628 }
6629
6630 return bRet;
6631}
6632
6633/* ======================================================================
6634 FUNCTION
6635 omx_vdec::ReleaseDone
6636
6637 DESCRIPTION
6638 Checks if IL client has released all the buffers.
6639
6640 PARAMETERS
6641 None.
6642
6643 RETURN VALUE
6644 true/false
6645
6646 ========================================================================== */
6647bool omx_vdec::release_done(void)
6648{
6649 bool bRet = false;
6650
6651 if (release_input_done()) {
6652 if (release_output_done()) {
6653 bRet = true;
6654 }
6655 }
6656 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006657}
6658
6659
6660/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006661 FUNCTION
6662 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006663
Arun Menon906de572013-06-18 17:01:40 -07006664 DESCRIPTION
6665 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006666
Arun Menon906de572013-06-18 17:01:40 -07006667 PARAMETERS
6668 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006669
Arun Menon906de572013-06-18 17:01:40 -07006670 RETURN VALUE
6671 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006672
Arun Menon906de572013-06-18 17:01:40 -07006673 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006674bool omx_vdec::release_output_done(void)
6675{
Arun Menon906de572013-06-18 17:01:40 -07006676 bool bRet = false;
6677 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006678
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006679 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006680 if (m_out_mem_ptr) {
6681 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6682 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6683 break;
6684 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006685 }
Arun Menon906de572013-06-18 17:01:40 -07006686 if (j == drv_ctx.op_buf.actualcount) {
6687 m_out_bm_count = 0;
6688 bRet = true;
6689 }
6690 } else {
6691 m_out_bm_count = 0;
6692 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006693 }
Arun Menon906de572013-06-18 17:01:40 -07006694 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006695}
6696/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006697 FUNCTION
6698 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006699
Arun Menon906de572013-06-18 17:01:40 -07006700 DESCRIPTION
6701 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006702
Arun Menon906de572013-06-18 17:01:40 -07006703 PARAMETERS
6704 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006705
Arun Menon906de572013-06-18 17:01:40 -07006706 RETURN VALUE
6707 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006708
Arun Menon906de572013-06-18 17:01:40 -07006709 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006710bool omx_vdec::release_input_done(void)
6711{
Arun Menon906de572013-06-18 17:01:40 -07006712 bool bRet = false;
6713 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006714
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006715 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006716 if (m_inp_mem_ptr) {
6717 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6718 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6719 break;
6720 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006721 }
Arun Menon906de572013-06-18 17:01:40 -07006722 if (j==drv_ctx.ip_buf.actualcount) {
6723 bRet = true;
6724 }
6725 } else {
6726 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006727 }
Arun Menon906de572013-06-18 17:01:40 -07006728 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006729}
6730
6731OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006732 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006733{
Arun Menon906de572013-06-18 17:01:40 -07006734 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306735 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006736 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006737 return OMX_ErrorBadParameter;
6738 } else if (output_flush_progress) {
6739 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6740 buffer->nFilledLen = 0;
6741 buffer->nTimeStamp = 0;
6742 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6743 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6744 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006745 }
6746
Arun Menon906de572013-06-18 17:01:40 -07006747 if (m_debug_extradata) {
6748 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006749 DEBUG_PRINT_HIGH("");
6750 DEBUG_PRINT_HIGH("***************************************************");
6751 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6752 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006753 }
6754
6755 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006756 DEBUG_PRINT_HIGH("");
6757 DEBUG_PRINT_HIGH("***************************************************");
6758 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6759 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006760 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006761 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006762
6763
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006764 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006765 buffer, buffer->pBuffer);
6766 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006767
Arun Menon906de572013-06-18 17:01:40 -07006768 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006769 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006770 if (!output_flush_progress)
6771 post_event((unsigned)NULL, (unsigned)NULL,
6772 OMX_COMPONENT_GENERATE_EOS_DONE);
6773
6774 if (psource_frame) {
6775 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6776 psource_frame = NULL;
6777 }
6778 if (pdest_frame) {
6779 pdest_frame->nFilledLen = 0;
6780 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6781 (unsigned)NULL);
6782 pdest_frame = NULL;
6783 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006784 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006785
Shalaj Jain273b3e02012-06-22 19:08:03 -07006786
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006787 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6788 DEBUG_PRINT_LOW("Processing extradata");
6789 handle_extradata(buffer);
6790 }
6791
Arun Menon906de572013-06-18 17:01:40 -07006792 /* For use buffer we need to copy the data */
6793 if (!output_flush_progress) {
6794 /* This is the error check for non-recoverable errros */
6795 bool is_duplicate_ts_valid = true;
6796 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006797
Arun Menon906de572013-06-18 17:01:40 -07006798 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6799 output_capability == V4L2_PIX_FMT_MPEG2 ||
6800 output_capability == V4L2_PIX_FMT_DIVX ||
6801 output_capability == V4L2_PIX_FMT_DIVX_311)
6802 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006803
Arun Menon906de572013-06-18 17:01:40 -07006804 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
Arun Menon7b6fd642014-02-13 16:48:36 -08006805 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
Arun Menon906de572013-06-18 17:01:40 -07006806 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306807 }
Arun Menon906de572013-06-18 17:01:40 -07006808 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306809
Arun Menon906de572013-06-18 17:01:40 -07006810 if (buffer->nFilledLen > 0) {
6811 time_stamp_dts.get_next_timestamp(buffer,
6812 is_interlaced && is_duplicate_ts_valid);
6813 if (m_debug_timestamp) {
6814 {
6815 OMX_TICKS expected_ts = 0;
6816 m_timestamp_list.pop_min_ts(expected_ts);
6817 if (is_interlaced && is_duplicate_ts_valid) {
6818 m_timestamp_list.pop_min_ts(expected_ts);
6819 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006820 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006821 buffer->nTimeStamp, expected_ts);
6822
6823 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006824 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006825 }
6826 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306827 }
Arun Menon906de572013-06-18 17:01:40 -07006828 } else {
Arun Menon906de572013-06-18 17:01:40 -07006829 time_stamp_dts.remove_time_stamp(
6830 buffer->nTimeStamp,
6831 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306832 }
Arun Menon906de572013-06-18 17:01:40 -07006833
6834
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006835 }
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006836
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07006837 /* Since we're passing around handles, adjust nFilledLen and nAllocLen
6838 * to size of the handle. Do it _after_ handle_extradata() which
6839 * requires the respective sizes to be accurate. */
6840 if (dynamic_buf_mode) {
6841 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
6842 buffer->nFilledLen = buffer->nFilledLen ?
6843 sizeof(struct VideoDecoderOutputMetaData) : 0;
6844 }
6845
Arun Menon906de572013-06-18 17:01:40 -07006846 if (m_cb.FillBufferDone) {
6847 if (buffer->nFilledLen > 0) {
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006848 if (arbitrary_bytes)
Arun Menon906de572013-06-18 17:01:40 -07006849 adjust_timestamp(buffer->nTimeStamp);
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08006850 else
6851 set_frame_rate(buffer->nTimeStamp);
6852
Arun Menon906de572013-06-18 17:01:40 -07006853 if (perf_flag) {
6854 if (!proc_frms) {
6855 dec_time.stop();
6856 latency = dec_time.processing_time_us() - latency;
6857 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6858 dec_time.start();
6859 fps_metrics.start();
6860 }
6861 proc_frms++;
6862 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6863 OMX_U64 proc_time = 0;
6864 fps_metrics.stop();
6865 proc_time = fps_metrics.processing_time_us();
6866 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006867 proc_frms, (float)proc_time / 1e6,
6868 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006869 proc_frms = 0;
6870 }
6871 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006872
6873#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006874 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006875
Arun Menon906de572013-06-18 17:01:40 -07006876 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6877 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6878 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6879 buffer->nFilledLen + 3)&(~3));
6880 while (p_extra &&
6881 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006882 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006883 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6884 if (p_extra->eType == OMX_ExtraDataNone) {
6885 break;
6886 }
6887 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6888 }
6889 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006890#endif
Arun Menon906de572013-06-18 17:01:40 -07006891 }
6892 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6893 prev_ts = LLONG_MAX;
6894 rst_prev_ts = true;
6895 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006896
Arun Menon906de572013-06-18 17:01:40 -07006897 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6898 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6899 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006900 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006901 OMX_BUFFERHEADERTYPE *il_buffer;
6902 il_buffer = client_buffers.get_il_buf_hdr(buffer);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006903
vivek mehta79cff222014-01-22 12:17:07 -08006904 if (il_buffer && m_last_rendered_TS >= 0) {
6905 int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
Manikanta Kanamarlapudifb53b262014-01-20 16:12:47 +05306906 OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
vivek mehta79cff222014-01-22 12:17:07 -08006907
6908 // Current frame can be send for rendering if
6909 // (a) current FPS is <= 60
6910 // (b) is the next frame after the frame with TS 0
6911 // (c) is the first frame after seek
6912 // (d) the delta TS b\w two consecutive frames is > 16 ms
6913 // (e) its TS is equal to previous frame TS
6914 // (f) if marked EOS
6915
6916 if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
6917 il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
6918 ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006919 m_last_rendered_TS = il_buffer->nTimeStamp;
vivek mehta79cff222014-01-22 12:17:07 -08006920 } else {
vivek mehtaa75c69f2014-01-10 21:50:37 -08006921 //mark for droping
vivek mehtaa75c69f2014-01-10 21:50:37 -08006922 buffer->nFilledLen = 0;
vivek mehta79cff222014-01-22 12:17:07 -08006923 }
6924
6925 DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%d)",
6926 buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
6927 il_buffer->nTimeStamp,ts_delta);
vivek mehtaa75c69f2014-01-10 21:50:37 -08006928 }
6929
vivek mehta79cff222014-01-22 12:17:07 -08006930 if (il_buffer) {
Arun Menon9230eb82014-02-11 19:19:02 -08006931 log_output_buffers(il_buffer);
6932 if (dynamic_buf_mode) {
6933 unsigned int nPortIndex = 0;
6934 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6935
6936 if (!secure_mode) {
6937 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6938 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6939 }
6940
6941 //Clear graphic buffer handles in dynamic mode
6942 native_buffer[nPortIndex].privatehandle = NULL;
6943 native_buffer[nPortIndex].nativehandle = NULL;
6944 }
Arun Menon906de572013-06-18 17:01:40 -07006945 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
vivek mehta79cff222014-01-22 12:17:07 -08006946 } else {
Arun Menon906de572013-06-18 17:01:40 -07006947 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6948 return OMX_ErrorBadParameter;
6949 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006950 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006951 } else {
6952 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006953 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006954
Praveen Chavancf924182013-12-06 23:16:23 -08006955#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306956 if (m_smoothstreaming_mode && m_out_mem_ptr) {
Praveen Chavancf924182013-12-06 23:16:23 -08006957 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6958 BufferDim_t dim;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306959 private_handle_t *private_handle = NULL;
Pushkaraj Patil065b5732014-11-26 11:08:02 +05306960 dim.sliceWidth = framesize.nWidth;
6961 dim.sliceHeight = framesize.nHeight;
Pushkaraj Patil8f98adf2014-02-12 13:32:00 +05306962 if (native_buffer[buf_index].privatehandle)
6963 private_handle = native_buffer[buf_index].privatehandle;
Praveen Chavancf924182013-12-06 23:16:23 -08006964 if (private_handle) {
6965 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6966 dim.sliceWidth, dim.sliceHeight);
6967 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6968 }
6969 }
6970#endif
6971
Arun Menon906de572013-06-18 17:01:40 -07006972 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006973}
6974
6975OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006976 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006977{
6978
Surajit Podderd2644d52013-08-28 17:59:06 +05306979 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006980 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006981 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006982 }
6983
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006984 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006985 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006986 pending_input_buffers--;
6987
Arun Menon906de572013-06-18 17:01:40 -07006988 if (arbitrary_bytes) {
6989 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006990 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006991 pdest_frame = buffer;
6992 buffer->nFilledLen = 0;
6993 buffer->nTimeStamp = LLONG_MAX;
6994 push_input_buffer (hComp);
6995 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006996 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006997 buffer->nFilledLen = 0;
6998 if (!m_input_free_q.insert_entry((unsigned)buffer,
6999 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007000 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07007001 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007002 }
Arun Menon906de572013-06-18 17:01:40 -07007003 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007004 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007005 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007006 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
7007 }
7008 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
7009 }
7010 return OMX_ErrorNone;
7011}
7012
Shalaj Jain273b3e02012-06-22 19:08:03 -07007013int omx_vdec::async_message_process (void *context, void* message)
7014{
Arun Menon906de572013-06-18 17:01:40 -07007015 omx_vdec* omx = NULL;
7016 struct vdec_msginfo *vdec_msg = NULL;
7017 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
7018 struct v4l2_buffer *v4l2_buf_ptr = NULL;
7019 struct vdec_output_frameinfo *output_respbuf = NULL;
7020 int rc=1;
7021 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007022 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07007023 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007024 }
Arun Menon906de572013-06-18 17:01:40 -07007025 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007026
Arun Menon906de572013-06-18 17:01:40 -07007027 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07007028
Arun Menon906de572013-06-18 17:01:40 -07007029 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007030
Arun Menon906de572013-06-18 17:01:40 -07007031 case VDEC_MSG_EVT_HW_ERROR:
7032 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7033 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7034 break;
7035
Deepak Verma24720fb2014-01-29 16:57:40 +05307036 case VDEC_MSG_EVT_HW_OVERLOAD:
7037 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7038 OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
7039 break;
7040
Arun Menon906de572013-06-18 17:01:40 -07007041 case VDEC_MSG_RESP_START_DONE:
7042 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7043 OMX_COMPONENT_GENERATE_START_DONE);
7044 break;
7045
7046 case VDEC_MSG_RESP_STOP_DONE:
7047 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7048 OMX_COMPONENT_GENERATE_STOP_DONE);
7049 break;
7050
7051 case VDEC_MSG_RESP_RESUME_DONE:
7052 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7053 OMX_COMPONENT_GENERATE_RESUME_DONE);
7054 break;
7055
7056 case VDEC_MSG_RESP_PAUSE_DONE:
7057 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7058 OMX_COMPONENT_GENERATE_PAUSE_DONE);
7059 break;
7060
7061 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
7062 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7063 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
7064 break;
7065 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
7066 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
7067 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
7068 break;
7069 case VDEC_MSG_RESP_INPUT_FLUSHED:
7070 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
7071
7072 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
7073 vdec_msg->msgdata.input_frame_clientdata; */
7074
7075 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
7076 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
7077 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05307078 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07007079 omxhdr = NULL;
7080 vdec_msg->status_code = VDEC_S_EFATAL;
7081 }
7082 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
7083 DEBUG_PRINT_HIGH("Unsupported input");
7084 omx->omx_report_error ();
7085 }
7086 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
7087 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
7088 }
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307089 if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307090
Pushkaraj Patilc7e0b9a2015-01-22 18:31:13 +05307091 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
7092 android_atomic_dec(&omx->m_queued_codec_config_count);
7093 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
7094 BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
7095 DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307096 sem_post(&omx->m_safe_flush);
7097 }
Pushkaraj Patil673f14a2014-12-03 14:55:19 +05307098 }
7099
Arun Menon906de572013-06-18 17:01:40 -07007100 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
7101 OMX_COMPONENT_GENERATE_EBD);
7102 break;
7103 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
7104 int64_t *timestamp;
7105 timestamp = (int64_t *) malloc(sizeof(int64_t));
7106 if (timestamp) {
7107 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
7108 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
7109 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007110 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07007111 vdec_msg->msgdata.output_frame.time_stamp);
7112 }
7113 break;
7114 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
7115 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
7116
7117 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
7118 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307119
7120 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 -07007121 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307122 vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
7123 (unsigned int)vdec_msg->msgdata.output_frame.len,
7124 vdec_msg->msgdata.output_frame.framesize.left,
7125 vdec_msg->msgdata.output_frame.framesize.top,
7126 vdec_msg->msgdata.output_frame.framesize.right,
7127 vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07007128
7129 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05307130 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07007131 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05307132 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307133
Deva Ramasubramaniancdbd31b2014-04-14 20:14:28 -07007134 if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
Arun Menon906de572013-06-18 17:01:40 -07007135 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
7136 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
7137 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
7138 omxhdr->nFlags = 0;
7139
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07007140 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07007141 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
7142 //rc = -1;
7143 }
7144 if (omxhdr->nFilledLen) {
7145 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
7146 }
7147 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
7148 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
7149 } else {
7150 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
7151 }
7152 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
7153 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7154 }
7155 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
7156 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
7157 }
Arun Menon7b6fd642014-02-13 16:48:36 -08007158
7159 if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
7160 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
7161 }
7162
Arun Menonbdb80b02013-08-12 17:45:54 -07007163 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07007164 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07007165 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
7166 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
7167 }
Arun Menonbdb80b02013-08-12 17:45:54 -07007168 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
7169 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
7170 omxhdr->nOffset);
7171 }
Arun Menon906de572013-06-18 17:01:40 -07007172 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
7173 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07007174 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07007175 omx->time_stamp_dts.remove_time_stamp(
7176 omxhdr->nTimeStamp,
7177 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
7178 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07007179 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
7180 OMX_COMPONENT_GENERATE_FTB);
7181 break;
7182 }
7183 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
7184 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7185 }
7186 vdec_msg->msgdata.output_frame.bufferaddr =
7187 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307188
7189 /* Post event if resolution OR crop changed */
7190 /* filled length will be changed if resolution changed */
7191 /* Crop parameters can be changed even without resolution change */
7192 if (omxhdr->nFilledLen
7193 && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
7194 || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
7195 || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
7196 || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05307197 || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
7198 || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
7199 || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307200
Maheshwar Ajja3cdbad42014-08-12 17:00:59 +05307201 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",
7202 omx->prev_n_filled_len,
7203 omx->drv_ctx.video_resolution.frame_width,
7204 omx->drv_ctx.video_resolution.frame_height,
7205 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
7206 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
7207 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
7208 vdec_msg->msgdata.output_frame.picsize.frame_height,
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307209 vdec_msg->msgdata.output_frame.framesize.left,
7210 vdec_msg->msgdata.output_frame.framesize.top,
7211 vdec_msg->msgdata.output_frame.framesize.right,
7212 vdec_msg->msgdata.output_frame.framesize.bottom);
7213
Maheshwar Ajja0f840ce2014-09-29 16:53:42 +05307214 omx->drv_ctx.video_resolution.frame_width =
7215 vdec_msg->msgdata.output_frame.picsize.frame_width;
7216 omx->drv_ctx.video_resolution.frame_height =
7217 vdec_msg->msgdata.output_frame.picsize.frame_height;
Praneeth Paladuguca80be72014-10-22 23:48:54 -07007218 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
7219 omx->drv_ctx.video_resolution.stride =
7220 VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
7221 omx->drv_ctx.video_resolution.scan_lines =
7222 VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
7223 }
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307224 memcpy(&omx->drv_ctx.frame_size,
7225 &vdec_msg->msgdata.output_frame.framesize,
7226 sizeof(struct vdec_framesize));
7227
7228 omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
7229 OMX_IndexConfigCommonOutputCrop,
7230 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Arun Menon906de572013-06-18 17:01:40 -07007231 }
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307232
Arun Menon906de572013-06-18 17:01:40 -07007233 if (omxhdr->nFilledLen)
7234 omx->prev_n_filled_len = omxhdr->nFilledLen;
7235
7236 output_respbuf = (struct vdec_output_frameinfo *)\
7237 omxhdr->pOutputPortPrivate;
7238 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
7239 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307240
Arun Menon906de572013-06-18 17:01:40 -07007241 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
7242 output_respbuf->pic_type = PICTURE_TYPE_I;
7243 }
7244 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
7245 output_respbuf->pic_type = PICTURE_TYPE_P;
7246 }
7247 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
7248 output_respbuf->pic_type = PICTURE_TYPE_B;
7249 }
7250
7251 if (omx->output_use_buffer)
7252 memcpy ( omxhdr->pBuffer, (void *)
7253 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
7254 (unsigned long)vdec_msg->msgdata.output_frame.offset),
7255 vdec_msg->msgdata.output_frame.len);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307256 } else {
7257 DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
7258 (unsigned int)vdec_msg->msgdata.output_frame.len,
7259 omxhdr->nAllocLen, omx->prev_n_filled_len);
Arun Menon906de572013-06-18 17:01:40 -07007260 omxhdr->nFilledLen = 0;
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307261 }
7262
Arun Menon906de572013-06-18 17:01:40 -07007263 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
7264 OMX_COMPONENT_GENERATE_FBD);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307265
7266 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07007267 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7268 OMX_COMPONENT_GENERATE_EOS_DONE);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307269 } else {
Arun Menon906de572013-06-18 17:01:40 -07007270 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
7271 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
Maheshwar Ajjac366ad22014-07-09 17:31:13 +05307272 }
Arun Menon906de572013-06-18 17:01:40 -07007273 break;
7274 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007275 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07007276 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7277 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
7278 break;
7279 default:
7280 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007281 }
Arun Menon906de572013-06-18 17:01:40 -07007282 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007283}
7284
7285OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07007286 OMX_HANDLETYPE hComp,
7287 OMX_BUFFERHEADERTYPE *buffer
7288 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07007289{
Arun Menon906de572013-06-18 17:01:40 -07007290 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007291 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007292
Arun Menon906de572013-06-18 17:01:40 -07007293 if (buffer == NULL) {
7294 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007295 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007296 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7297 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007298 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
7299
7300 /* return zero length and not an EOS buffer */
7301 /* return buffer if input flush in progress */
7302 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7303 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007304 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07007305 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7306 return OMX_ErrorNone;
7307 }
7308
7309 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007310 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007311 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007312 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07007313 push_input_buffer (hComp);
7314 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007315 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07007316 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7317 (unsigned)NULL)) {
7318 return OMX_ErrorBadParameter;
7319 }
7320 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007321
Sowmya Pandiri302f5ab2014-04-03 13:41:03 -07007322 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
7323 codec_config_flag = false;
7324 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007325
Arun Menon906de572013-06-18 17:01:40 -07007326 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007327}
7328
7329OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7330{
Arun Menon906de572013-06-18 17:01:40 -07007331 unsigned address,p2,id;
7332 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007333
Arun Menon906de572013-06-18 17:01:40 -07007334 if (pdest_frame == NULL || psource_frame == NULL) {
7335 /*Check if we have a destination buffer*/
7336 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007337 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007338 if (m_input_free_q.m_size) {
7339 m_input_free_q.pop_entry(&address,&p2,&id);
7340 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7341 pdest_frame->nFilledLen = 0;
7342 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007343 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007344 }
7345 }
7346
7347 /*Check if we have a destination buffer*/
7348 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007349 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07007350 if (m_input_pending_q.m_size) {
7351 m_input_pending_q.pop_entry(&address,&p2,&id);
7352 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007353 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007354 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007355 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007356 psource_frame->nFlags,psource_frame->nFilledLen);
7357
7358 }
7359 }
7360
Shalaj Jain273b3e02012-06-22 19:08:03 -07007361 }
7362
Arun Menon906de572013-06-18 17:01:40 -07007363 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7364 switch (codec_type_parse) {
7365 case CODEC_TYPE_MPEG4:
7366 case CODEC_TYPE_H263:
7367 case CODEC_TYPE_MPEG2:
7368 ret = push_input_sc_codec(hComp);
7369 break;
7370 case CODEC_TYPE_H264:
7371 ret = push_input_h264(hComp);
7372 break;
7373 case CODEC_TYPE_VC1:
7374 ret = push_input_vc1(hComp);
7375 break;
7376 default:
7377 break;
7378 }
7379 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007380 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007381 omx_report_error ();
7382 break;
7383 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007384 }
7385
Arun Menon906de572013-06-18 17:01:40 -07007386 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007387}
7388
7389OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7390{
Arun Menon906de572013-06-18 17:01:40 -07007391 OMX_U32 partial_frame = 1;
7392 OMX_BOOL generate_ebd = OMX_TRUE;
7393 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007394
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007395 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007396 psource_frame,psource_frame->nTimeStamp);
7397 if (m_frame_parser.parse_sc_frame(psource_frame,
7398 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007399 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007400 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007401 }
Arun Menon906de572013-06-18 17:01:40 -07007402
7403 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007404 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007405 pdest_frame->nFilledLen,psource_frame,frame_count);
7406
7407
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007408 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007409 /*First Parsed buffer will have only header Hence skip*/
7410 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007411 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007412
7413 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7414 codec_type_parse == CODEC_TYPE_DIVX) {
7415 mp4StreamType psBits;
7416 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7417 psBits.numBytes = pdest_frame->nFilledLen;
7418 mp4_headerparser.parseHeader(&psBits);
7419 }
7420
7421 frame_count++;
7422 } else {
7423 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7424 if (pdest_frame->nFilledLen) {
7425 /*Push the frame to the Decoder*/
7426 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7427 return OMX_ErrorBadParameter;
7428 }
7429 frame_count++;
7430 pdest_frame = NULL;
7431
7432 if (m_input_free_q.m_size) {
7433 m_input_free_q.pop_entry(&address,&p2,&id);
7434 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7435 pdest_frame->nFilledLen = 0;
7436 }
7437 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007438 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007439 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7440 (unsigned)NULL);
7441 pdest_frame = NULL;
7442 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007443 }
Arun Menon906de572013-06-18 17:01:40 -07007444 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007445 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007446 /*Check if Destination Buffer is full*/
7447 if (pdest_frame->nAllocLen ==
7448 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007449 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007450 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007451 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007452 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007453
Arun Menon906de572013-06-18 17:01:40 -07007454 if (psource_frame->nFilledLen == 0) {
7455 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7456 if (pdest_frame) {
7457 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007458 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007459 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007460 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007461 pdest_frame->nFilledLen,frame_count++);
7462 /*Push the frame to the Decoder*/
7463 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7464 return OMX_ErrorBadParameter;
7465 }
7466 frame_count++;
7467 pdest_frame = NULL;
7468 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007469 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007470 generate_ebd = OMX_FALSE;
7471 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007472 }
Arun Menon906de572013-06-18 17:01:40 -07007473 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007474 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007475 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7476 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007477
Arun Menon906de572013-06-18 17:01:40 -07007478 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007479 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007480 m_input_pending_q.pop_entry(&address,&p2,&id);
7481 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007482 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007483 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007484 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007485 psource_frame->nFlags,psource_frame->nFilledLen);
7486 }
7487 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007488 }
Arun Menon906de572013-06-18 17:01:40 -07007489 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007490}
7491
7492OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7493{
Arun Menon906de572013-06-18 17:01:40 -07007494 OMX_U32 partial_frame = 1;
7495 unsigned address = 0, p2 = 0, id = 0;
7496 OMX_BOOL isNewFrame = OMX_FALSE;
7497 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007498
Arun Menon906de572013-06-18 17:01:40 -07007499 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007500 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007501 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007502 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007503 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007504 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007505 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007506 if (h264_scratch.nFilledLen && look_ahead_nal) {
7507 look_ahead_nal = false;
7508 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7509 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007510 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7511 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7512 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007513 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007514 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007515 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007516 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007517 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007518 }
Arun Menon906de572013-06-18 17:01:40 -07007519 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007520
7521 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7522 in EOS flag getting associated with the destination
7523 */
7524 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7525 pdest_frame->nFilledLen) {
7526 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7527 generate_ebd = OMX_FALSE;
7528 }
7529
Arun Menon906de572013-06-18 17:01:40 -07007530 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007531 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007532 if (m_frame_parser.parse_sc_frame(psource_frame,
7533 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007534 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007535 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007536 }
Arun Menon906de572013-06-18 17:01:40 -07007537 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007538 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007539 if (m_frame_parser.parse_h264_nallength(psource_frame,
7540 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007541 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007542 return OMX_ErrorBadParameter;
7543 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007544 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007545
Arun Menon906de572013-06-18 17:01:40 -07007546 if (partial_frame == 0) {
7547 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007548 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007549 nal_count++;
7550 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7551 h264_scratch.nFlags = psource_frame->nFlags;
7552 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007553 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007554 if (h264_scratch.nFilledLen) {
7555 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7556 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007557#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007558 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7559 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7560 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7561 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7562 // If timeinfo is present frame info from SEI is already processed
7563 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7564 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007565#endif
Arun Menon906de572013-06-18 17:01:40 -07007566 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7567 nal_count++;
7568 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7569 pdest_frame->nTimeStamp = h264_last_au_ts;
7570 pdest_frame->nFlags = h264_last_au_flags;
7571#ifdef PANSCAN_HDLR
7572 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7573 h264_parser->update_panscan_data(h264_last_au_ts);
7574#endif
7575 }
7576 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7577 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7578 h264_last_au_ts = h264_scratch.nTimeStamp;
7579 h264_last_au_flags = h264_scratch.nFlags;
7580#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7581 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7582 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7583 if (!VALID_TS(h264_last_au_ts))
7584 h264_last_au_ts = ts_in_sei;
7585 }
7586#endif
7587 } else
7588 h264_last_au_ts = LLONG_MAX;
7589 }
7590
7591 if (!isNewFrame) {
7592 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7593 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007594 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007595 h264_scratch.nFilledLen);
7596 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7597 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7598 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7599 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7600 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7601 h264_scratch.nFilledLen = 0;
7602 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007603 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007604 return OMX_ErrorBadParameter;
7605 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007606 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007607 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007608 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007609 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007610 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007611 pdest_frame->nFilledLen,frame_count++);
7612
7613 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007614 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007615 look_ahead_nal = false;
7616 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7617 h264_scratch.nFilledLen) {
7618 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7619 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7620 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7621 h264_scratch.nFilledLen = 0;
7622 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007623 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007624 return OMX_ErrorBadParameter;
7625 }
7626 } else {
7627 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007628 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007629 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7630 }
7631 /*Push the frame to the Decoder*/
7632 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7633 return OMX_ErrorBadParameter;
7634 }
7635 //frame_count++;
7636 pdest_frame = NULL;
7637 if (m_input_free_q.m_size) {
7638 m_input_free_q.pop_entry(&address,&p2,&id);
7639 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007640 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007641 pdest_frame->nFilledLen = 0;
7642 pdest_frame->nFlags = 0;
7643 pdest_frame->nTimeStamp = LLONG_MAX;
7644 }
7645 }
7646 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007647 }
Arun Menon906de572013-06-18 17:01:40 -07007648 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007649 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007650 /*Check if Destination Buffer is full*/
7651 if (h264_scratch.nAllocLen ==
7652 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007653 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007654 return OMX_ErrorStreamCorrupt;
7655 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007656 }
Arun Menon906de572013-06-18 17:01:40 -07007657
7658 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007659 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007660
7661 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7662 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007663 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007664 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7665 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007666 if(pdest_frame->nFilledLen == 0) {
7667 /* No residual frame from before, send whatever
7668 * we have left */
7669 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7670 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7671 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7672 h264_scratch.nFilledLen = 0;
7673 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7674 } else {
7675 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7676 if(!isNewFrame) {
7677 /* Have a residual frame, but we know that the
7678 * AU in this frame is belonging to whatever
7679 * frame we had left over. So append it */
7680 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7681 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7682 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7683 h264_scratch.nFilledLen = 0;
Balamurugan Alagarsamyefde3832014-09-22 19:52:20 +05307684 if (h264_last_au_ts != LLONG_MAX)
7685 pdest_frame->nTimeStamp = h264_last_au_ts;
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007686 } else {
7687 /* Completely new frame, let's just push what
7688 * we have now. The resulting EBD would trigger
7689 * another push */
7690 generate_ebd = OMX_FALSE;
7691 pdest_frame->nTimeStamp = h264_last_au_ts;
7692 h264_last_au_ts = h264_scratch.nTimeStamp;
7693 }
7694 }
Arun Menon906de572013-06-18 17:01:40 -07007695 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007696 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007697 return OMX_ErrorBadParameter;
7698 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007699
7700 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7701 if(generate_ebd == OMX_TRUE) {
7702 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7703 }
Arun Menon906de572013-06-18 17:01:40 -07007704
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007705 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007706 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007707 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007708#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7709 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7710 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7711 if (!VALID_TS(pdest_frame->nTimeStamp))
7712 pdest_frame->nTimeStamp = ts_in_sei;
7713 }
7714#endif
7715 /*Push the frame to the Decoder*/
7716 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7717 return OMX_ErrorBadParameter;
7718 }
7719 frame_count++;
7720 pdest_frame = NULL;
7721 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007722 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007723 pdest_frame,h264_scratch.nFilledLen);
7724 generate_ebd = OMX_FALSE;
7725 }
7726 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007727 }
Arun Menon906de572013-06-18 17:01:40 -07007728 if (generate_ebd && !psource_frame->nFilledLen) {
7729 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7730 psource_frame = NULL;
7731 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007732 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007733 m_input_pending_q.pop_entry(&address,&p2,&id);
7734 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007735 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007736 psource_frame->nFlags,psource_frame->nFilledLen);
7737 }
7738 }
7739 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007740}
7741
7742OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7743{
7744 OMX_U8 *buf, *pdest;
7745 OMX_U32 partial_frame = 1;
7746 OMX_U32 buf_len, dest_len;
7747
Arun Menon906de572013-06-18 17:01:40 -07007748 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007749 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007750 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007751 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007752 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007753 buf = psource_frame->pBuffer;
7754 buf_len = psource_frame->nFilledLen;
7755
7756 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007757 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007758 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007759 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007760 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007761 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007762 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007763 return OMX_ErrorStreamCorrupt;
7764 }
Arun Menon906de572013-06-18 17:01:40 -07007765 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007766 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7767 pdest_frame->nOffset;
7768 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007769 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007770
Arun Menon906de572013-06-18 17:01:40 -07007771 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007772 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007773 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007774 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007775 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7776 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7777 }
7778 }
7779 }
7780
Arun Menon906de572013-06-18 17:01:40 -07007781 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007782 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007783 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007784 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007785 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007786 return OMX_ErrorBadParameter;
7787 }
Arun Menon906de572013-06-18 17:01:40 -07007788 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007789
7790 case VC1_SP_MP_RCV:
7791 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007792 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007793 return OMX_ErrorBadParameter;
7794 }
7795 return OMX_ErrorNone;
7796}
7797
David Ng38e2d232013-03-15 20:05:58 -07007798#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007799bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007800 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007801{
Arun Menon906de572013-06-18 17:01:40 -07007802 struct pmem_allocation allocation;
7803 allocation.size = buffer_size;
7804 allocation.align = clip2(alignment);
7805 if (allocation.align < 4096) {
7806 allocation.align = 4096;
7807 }
7808 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007809 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007810 allocation.align, allocation.size);
7811 return false;
7812 }
7813 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007814}
David Ng38e2d232013-03-15 20:05:58 -07007815#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007816#ifdef USE_ION
7817int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007818 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7819 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007820{
Arun Menon906de572013-06-18 17:01:40 -07007821 int fd = -EINVAL;
7822 int rc = -EINVAL;
7823 int ion_dev_flag;
7824 struct vdec_ion ion_buf_info;
7825 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007826 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007827 return -EINVAL;
7828 }
7829 ion_dev_flag = O_RDONLY;
7830 fd = open (MEM_DEVICE, ion_dev_flag);
7831 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007832 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007833 return fd;
7834 }
7835 alloc_data->flags = 0;
7836 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7837 alloc_data->flags |= ION_FLAG_CACHED;
7838 }
7839 alloc_data->len = buffer_size;
7840 alloc_data->align = clip2(alignment);
7841 if (alloc_data->align < 4096) {
7842 alloc_data->align = 4096;
7843 }
7844 if ((secure_mode) && (flag & ION_SECURE))
7845 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007846
Arun Menon906de572013-06-18 17:01:40 -07007847 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307848 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007849 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7850 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7851 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007852 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007853 alloc_data->handle = NULL;
7854 close(fd);
7855 fd = -ENOMEM;
7856 return fd;
7857 }
7858 fd_data->handle = alloc_data->handle;
7859 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7860 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007861 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007862 ion_buf_info.ion_alloc_data = *alloc_data;
7863 ion_buf_info.ion_device_fd = fd;
7864 ion_buf_info.fd_ion_data = *fd_data;
7865 free_ion_memory(&ion_buf_info);
7866 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007867 fd = -ENOMEM;
7868 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007869
Arun Menon906de572013-06-18 17:01:40 -07007870 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007871}
7872
Arun Menon906de572013-06-18 17:01:40 -07007873void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7874{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007875
Arun Menon906de572013-06-18 17:01:40 -07007876 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007877 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007878 return;
7879 }
7880 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7881 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007882 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007883 }
7884 close(buf_ion_info->ion_device_fd);
7885 buf_ion_info->ion_device_fd = -1;
7886 buf_ion_info->ion_alloc_data.handle = NULL;
7887 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007888}
7889#endif
7890void omx_vdec::free_output_buffer_header()
7891{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007892 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007893 output_use_buffer = false;
7894 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007895
Arun Menon906de572013-06-18 17:01:40 -07007896 if (m_out_mem_ptr) {
7897 free (m_out_mem_ptr);
7898 m_out_mem_ptr = NULL;
7899 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007900
Arun Menon906de572013-06-18 17:01:40 -07007901 if (m_platform_list) {
7902 free(m_platform_list);
7903 m_platform_list = NULL;
7904 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007905
Arun Menon906de572013-06-18 17:01:40 -07007906 if (drv_ctx.ptr_respbuffer) {
7907 free (drv_ctx.ptr_respbuffer);
7908 drv_ctx.ptr_respbuffer = NULL;
7909 }
7910 if (drv_ctx.ptr_outputbuffer) {
7911 free (drv_ctx.ptr_outputbuffer);
7912 drv_ctx.ptr_outputbuffer = NULL;
7913 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007914#ifdef USE_ION
7915 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007916 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007917 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007918 drv_ctx.op_buf_ion_info = NULL;
7919 }
7920#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007921 if (out_dynamic_list) {
7922 free(out_dynamic_list);
7923 out_dynamic_list = NULL;
7924 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007925}
7926
7927void omx_vdec::free_input_buffer_header()
7928{
7929 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007930 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007931 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007932 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007933 free (m_inp_heap_ptr);
7934 m_inp_heap_ptr = NULL;
7935 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007936
Arun Menon906de572013-06-18 17:01:40 -07007937 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007938 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007939 free (m_phdr_pmem_ptr);
7940 m_phdr_pmem_ptr = NULL;
7941 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007942 }
Arun Menon906de572013-06-18 17:01:40 -07007943 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007944 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007945 free (m_inp_mem_ptr);
7946 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007947 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007948 /* We just freed all the buffer headers, every thing in m_input_free_q,
7949 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007950 while (m_input_free_q.m_size) {
7951 unsigned address, p2, id;
7952 m_input_free_q.pop_entry(&address, &p2, &id);
7953 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007954 while (m_input_pending_q.m_size) {
7955 unsigned address, p2, id;
7956 m_input_pending_q.pop_entry(&address, &p2, &id);
7957 }
7958 pdest_frame = NULL;
7959 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007960 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007961 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007962 free (drv_ctx.ptr_inputbuffer);
7963 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007964 }
7965#ifdef USE_ION
7966 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007967 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007968 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007969 drv_ctx.ip_buf_ion_info = NULL;
7970 }
7971#endif
7972}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007973
7974int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007975{
Arun Menon906de572013-06-18 17:01:40 -07007976 enum v4l2_buf_type btype;
7977 int rc = 0;
7978 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007979
Arun Menon906de572013-06-18 17:01:40 -07007980 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7981 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7982 v4l2_port = OUTPUT_PORT;
7983 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7984 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7985 v4l2_port = CAPTURE_PORT;
7986 } else if (port == OMX_ALL) {
7987 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7988 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007989
Arun Menon906de572013-06-18 17:01:40 -07007990 if (!rc_input)
7991 return rc_input;
7992 else
7993 return rc_output;
7994 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007995
Arun Menon906de572013-06-18 17:01:40 -07007996 if (!streaming[v4l2_port]) {
7997 // already streamed off, warn and move on
7998 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7999 " which is already streamed off", v4l2_port);
8000 return 0;
8001 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008002
Arun Menon906de572013-06-18 17:01:40 -07008003 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008004
Arun Menon906de572013-06-18 17:01:40 -07008005 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
8006 if (rc) {
8007 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008008 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07008009 } else {
8010 streaming[v4l2_port] = false;
8011 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07008012
Arun Menon906de572013-06-18 17:01:40 -07008013 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008014}
8015
8016OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
8017{
Arun Menon906de572013-06-18 17:01:40 -07008018 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8019 struct v4l2_requestbuffers bufreq;
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07008020 unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308021 unsigned int final_extra_data_size = 0;
Arun Menon906de572013-06-18 17:01:40 -07008022 struct v4l2_format fmt;
8023 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008024 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008025 buffer_prop->actualcount, buffer_prop->buffer_size);
8026 bufreq.memory = V4L2_MEMORY_USERPTR;
8027 bufreq.count = 1;
8028 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8029 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8030 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8031 fmt.fmt.pix_mp.pixelformat = output_capability;
8032 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8033 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8034 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8035 fmt.fmt.pix_mp.pixelformat = capture_capability;
8036 } else {
8037 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008038 }
Arun Menon906de572013-06-18 17:01:40 -07008039 if (eRet==OMX_ErrorNone) {
8040 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008041 }
Arun Menon906de572013-06-18 17:01:40 -07008042 if (ret) {
8043 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8044 /*TODO: How to handle this case */
8045 eRet = OMX_ErrorInsufficientResources;
8046 return eRet;
8047 } else {
8048 buffer_prop->actualcount = bufreq.count;
8049 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008050 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008051 }
Arun Menon906de572013-06-18 17:01:40 -07008052 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
8053 buffer_prop->actualcount, buffer_prop->buffer_size);
8054
8055 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8056 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
8057
8058 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8059
8060 update_resolution(fmt.fmt.pix_mp.width,
8061 fmt.fmt.pix_mp.height,
8062 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
8063 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
8064 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
8065 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008066 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07008067
8068 if (ret) {
8069 /*TODO: How to handle this case */
8070 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
8071 eRet = OMX_ErrorInsufficientResources;
8072 } else {
8073 int extra_idx = 0;
8074
8075 eRet = is_video_session_supported();
8076 if (eRet)
8077 return eRet;
8078
8079 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
8080 buf_size = buffer_prop->buffer_size;
8081 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
8082 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
8083 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
8084 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008085 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07008086 return OMX_ErrorBadParameter;
8087 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008088
Deva Ramasubramanian991d0db2014-05-08 15:02:24 -07008089 default_extra_data_size = VENUS_EXTRADATA_SIZE(
8090 drv_ctx.video_resolution.frame_height,
8091 drv_ctx.video_resolution.frame_width);
8092 final_extra_data_size = extra_data_size > default_extra_data_size ?
8093 extra_data_size : default_extra_data_size;
8094
8095 final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
8096 (~(buffer_prop->alignment - 1));
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07008097
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308098 drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07008099 drv_ctx.extradata_info.count = buffer_prop->actualcount;
Pushkaraj Patil1ab10292014-02-11 20:10:42 +05308100 drv_ctx.extradata_info.buffer_size = final_extra_data_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308101 if (!secure_mode)
8102 buf_size += final_extra_data_size;
Arun Menon906de572013-06-18 17:01:40 -07008103 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8104 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
8105 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008106 if (extra_data_size)
8107 DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%d)",
8108 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
8109
Arun Menon906de572013-06-18 17:01:40 -07008110 if (in_reconfig) // BufReq will be set to driver when port is disabled
8111 buffer_prop->buffer_size = buf_size;
8112 else if (buf_size != buffer_prop->buffer_size) {
8113 buffer_prop->buffer_size = buf_size;
8114 eRet = set_buffer_req(buffer_prop);
8115 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008116 }
Arun Menon906de572013-06-18 17:01:40 -07008117 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
8118 buffer_prop->actualcount, buffer_prop->buffer_size);
8119 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008120}
8121
8122OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
8123{
Arun Menon906de572013-06-18 17:01:40 -07008124 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8125 unsigned buf_size = 0;
8126 struct v4l2_format fmt;
8127 struct v4l2_requestbuffers bufreq;
8128 int ret;
8129 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
8130 buffer_prop->actualcount, buffer_prop->buffer_size);
8131 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
8132 if (buf_size != buffer_prop->buffer_size) {
8133 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
8134 buffer_prop->buffer_size, buf_size);
8135 eRet = OMX_ErrorBadParameter;
8136 } else {
8137 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
8138 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008139
Arun Menon906de572013-06-18 17:01:40 -07008140 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8141 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8142 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07008143 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07008144 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8145 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8146 fmt.fmt.pix_mp.pixelformat = capture_capability;
8147 } else {
8148 eRet = OMX_ErrorBadParameter;
8149 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07008150
Arun Menon906de572013-06-18 17:01:40 -07008151 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
8152 if (ret) {
8153 /*TODO: How to handle this case */
8154 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
8155 eRet = OMX_ErrorInsufficientResources;
8156 }
8157
8158 bufreq.memory = V4L2_MEMORY_USERPTR;
8159 bufreq.count = buffer_prop->actualcount;
8160 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
8161 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8162 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
8163 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8164 } else {
8165 eRet = OMX_ErrorBadParameter;
8166 }
8167
8168 if (eRet==OMX_ErrorNone) {
8169 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
8170 }
8171
8172 if (ret) {
8173 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
8174 /*TODO: How to handle this case */
8175 eRet = OMX_ErrorInsufficientResources;
8176 } else if (bufreq.count < buffer_prop->actualcount) {
8177 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8178 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8179 buffer_prop->actualcount, bufreq.count);
8180 eRet = OMX_ErrorInsufficientResources;
8181 } else {
8182 if (!client_buffers.update_buffer_req()) {
8183 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8184 eRet = OMX_ErrorInsufficientResources;
8185 }
8186 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008187 }
Arun Menon906de572013-06-18 17:01:40 -07008188 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008189}
8190
Shalaj Jain273b3e02012-06-22 19:08:03 -07008191OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8192{
Arun Menon906de572013-06-18 17:01:40 -07008193 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8194 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008195}
8196
8197OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8198{
Arun Menon906de572013-06-18 17:01:40 -07008199 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308200 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07008201 if (!portDefn) {
8202 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008203 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008204 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07008205 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8206 portDefn->nSize = sizeof(portDefn);
8207 portDefn->eDomain = OMX_PortDomainVideo;
8208 if (drv_ctx.frame_rate.fps_denominator > 0)
Deva Ramasubramanian9ba5d832014-01-03 18:32:50 -08008209 portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
8210 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
Arun Menon906de572013-06-18 17:01:40 -07008211 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008212 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07008213 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008214 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308215 memset(&fmt, 0x0, sizeof(struct v4l2_format));
Arun Menon906de572013-06-18 17:01:40 -07008216 if (0 == portDefn->nPortIndex) {
8217 portDefn->eDir = OMX_DirInput;
8218 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8219 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8220 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8221 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8222 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8223 portDefn->bEnabled = m_inp_bEnabled;
8224 portDefn->bPopulated = m_inp_bPopulated;
Pushkaraj Patil41588352014-02-25 20:51:34 +05308225
8226 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8227 fmt.fmt.pix_mp.pixelformat = output_capability;
Arun Menon906de572013-06-18 17:01:40 -07008228 } else if (1 == portDefn->nPortIndex) {
8229 unsigned int buf_size = 0;
8230 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008231 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07008232 return OMX_ErrorHardware;
8233 }
8234 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008235 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07008236 return OMX_ErrorHardware;
8237 }
8238 portDefn->nBufferSize = buf_size;
8239 portDefn->eDir = OMX_DirOutput;
8240 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8241 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
8242 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8243 portDefn->bEnabled = m_out_bEnabled;
8244 portDefn->bPopulated = m_out_bPopulated;
8245 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008246 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07008247 return OMX_ErrorHardware;
8248 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308249 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
8250 fmt.fmt.pix_mp.pixelformat = capture_capability;
Arun Menon906de572013-06-18 17:01:40 -07008251 } else {
8252 portDefn->eDir = OMX_DirMax;
8253 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8254 (int)portDefn->nPortIndex);
8255 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008256 }
Pushkaraj Patil41588352014-02-25 20:51:34 +05308257 if (is_down_scalar_enabled) {
8258 int ret = 0;
8259 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
8260 if (ret) {
8261 DEBUG_PRINT_ERROR("update_portdef : Error in getting port resolution");
8262 return OMX_ErrorHardware;
8263 } else {
8264 portDefn->format.video.nFrameWidth = fmt.fmt.pix_mp.width;
8265 portDefn->format.video.nFrameHeight = fmt.fmt.pix_mp.height;
8266 portDefn->format.video.nStride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
8267 portDefn->format.video.nSliceHeight = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
8268 }
8269 } else {
8270 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8271 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8272 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8273 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
8274 }
8275
Praveen Chavandb7776f2014-02-06 18:17:25 -08008276 if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
8277 (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
Maheshwar Ajja77cd19c2014-06-05 11:23:18 +05308278 portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16);
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308279 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
8280 }
8281 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
8282 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
8283 portDefn->nPortIndex,
8284 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07008285 portDefn->format.video.nFrameHeight,
8286 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308287 portDefn->format.video.nSliceHeight,
8288 portDefn->format.video.eColorFormat,
8289 portDefn->nBufferSize,
8290 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008291
Maheshwar Ajja507d6552014-01-03 14:54:29 +05308292 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008293}
8294
8295OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8296{
Arun Menon906de572013-06-18 17:01:40 -07008297 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8298 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8299 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008300
Arun Menon906de572013-06-18 17:01:40 -07008301 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008302 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07008303 int nBufHdrSize = 0;
8304 int nPlatformEntrySize = 0;
8305 int nPlatformListSize = 0;
8306 int nPMEMInfoSize = 0;
8307 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8308 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8309 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008310
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008311 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07008312 drv_ctx.op_buf.actualcount);
8313 nBufHdrSize = drv_ctx.op_buf.actualcount *
8314 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008315
Arun Menon906de572013-06-18 17:01:40 -07008316 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8317 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8318 nPlatformListSize = drv_ctx.op_buf.actualcount *
8319 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8320 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8321 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008322
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008323 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07008324 sizeof(OMX_BUFFERHEADERTYPE),
8325 nPMEMInfoSize,
8326 nPlatformListSize);
Steve Kondikf1914362015-11-01 02:50:41 -08008327 DEBUG_PRINT_LOW("PE %d bmSize %" PRId64, nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07008328 m_out_bm_count);
8329 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8330 // Alloc mem for platform specific info
8331 char *pPtr=NULL;
8332 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8333 nPMEMInfoSize,1);
8334 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8335 calloc (sizeof(struct vdec_bufferpayload),
8336 drv_ctx.op_buf.actualcount);
8337 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8338 calloc (sizeof (struct vdec_output_frameinfo),
8339 drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008340 if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
8341 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
8342 return OMX_ErrorInsufficientResources;
8343 }
8344
Shalaj Jain273b3e02012-06-22 19:08:03 -07008345#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008346 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8347 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Arun Menon8544ead2014-05-08 17:42:29 -07008348 if (!drv_ctx.op_buf_ion_info) {
8349 DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
8350 return OMX_ErrorInsufficientResources;
8351 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008352#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07008353 if (dynamic_buf_mode) {
8354 out_dynamic_list = (struct dynamic_buf_list *) \
8355 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
8356 }
Arun Menon906de572013-06-18 17:01:40 -07008357 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8358 && drv_ctx.ptr_respbuffer) {
8359 bufHdr = m_out_mem_ptr;
8360 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8361 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8362 (((char *) m_platform_list) + nPlatformListSize);
8363 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8364 (((char *) m_platform_entry) + nPlatformEntrySize);
8365 pPlatformList = m_platform_list;
8366 pPlatformEntry = m_platform_entry;
8367 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008368
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008369 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008370
Arun Menon906de572013-06-18 17:01:40 -07008371 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008372 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07008373 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008374 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07008375 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
8376 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8377 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8378 // Set the values when we determine the right HxW param
8379 bufHdr->nAllocLen = 0;
8380 bufHdr->nFilledLen = 0;
8381 bufHdr->pAppPrivate = NULL;
8382 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8383 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8384 pPlatformEntry->entry = pPMEMInfo;
8385 // Initialize the Platform List
8386 pPlatformList->nEntries = 1;
8387 pPlatformList->entryList = pPlatformEntry;
8388 // Keep pBuffer NULL till vdec is opened
8389 bufHdr->pBuffer = NULL;
8390 pPMEMInfo->offset = 0;
8391 pPMEMInfo->pmem_fd = 0;
8392 bufHdr->pPlatformPrivate = pPlatformList;
8393 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008394#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008395 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008396#endif
Arun Menon906de572013-06-18 17:01:40 -07008397 /*Create a mapping between buffers*/
8398 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8399 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8400 &drv_ctx.ptr_outputbuffer[i];
8401 // Move the buffer and buffer header pointers
8402 bufHdr++;
8403 pPMEMInfo++;
8404 pPlatformEntry++;
8405 pPlatformList++;
8406 }
8407 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008408 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008409 m_out_mem_ptr, pPtr);
8410 if (m_out_mem_ptr) {
8411 free(m_out_mem_ptr);
8412 m_out_mem_ptr = NULL;
8413 }
8414 if (pPtr) {
8415 free(pPtr);
8416 pPtr = NULL;
8417 }
8418 if (drv_ctx.ptr_outputbuffer) {
8419 free(drv_ctx.ptr_outputbuffer);
8420 drv_ctx.ptr_outputbuffer = NULL;
8421 }
8422 if (drv_ctx.ptr_respbuffer) {
8423 free(drv_ctx.ptr_respbuffer);
8424 drv_ctx.ptr_respbuffer = NULL;
8425 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008426#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008427 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008428 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008429 free(drv_ctx.op_buf_ion_info);
8430 drv_ctx.op_buf_ion_info = NULL;
8431 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008432#endif
Arun Menon906de572013-06-18 17:01:40 -07008433 eRet = OMX_ErrorInsufficientResources;
8434 }
8435 } else {
8436 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008437 }
Arun Menon906de572013-06-18 17:01:40 -07008438 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008439}
8440
8441void omx_vdec::complete_pending_buffer_done_cbs()
8442{
Arun Menon906de572013-06-18 17:01:40 -07008443 unsigned p1;
8444 unsigned p2;
8445 unsigned ident;
8446 omx_cmd_queue tmp_q, pending_bd_q;
8447 pthread_mutex_lock(&m_lock);
8448 // pop all pending GENERATE FDB from ftb queue
8449 while (m_ftb_q.m_size) {
8450 m_ftb_q.pop_entry(&p1,&p2,&ident);
8451 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8452 pending_bd_q.insert_entry(p1,p2,ident);
8453 } else {
8454 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008455 }
Arun Menon906de572013-06-18 17:01:40 -07008456 }
8457 //return all non GENERATE FDB to ftb queue
8458 while (tmp_q.m_size) {
8459 tmp_q.pop_entry(&p1,&p2,&ident);
8460 m_ftb_q.insert_entry(p1,p2,ident);
8461 }
8462 // pop all pending GENERATE EDB from etb queue
8463 while (m_etb_q.m_size) {
8464 m_etb_q.pop_entry(&p1,&p2,&ident);
8465 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8466 pending_bd_q.insert_entry(p1,p2,ident);
8467 } else {
8468 tmp_q.insert_entry(p1,p2,ident);
8469 }
8470 }
8471 //return all non GENERATE FDB to etb queue
8472 while (tmp_q.m_size) {
8473 tmp_q.pop_entry(&p1,&p2,&ident);
8474 m_etb_q.insert_entry(p1,p2,ident);
8475 }
8476 pthread_mutex_unlock(&m_lock);
8477 // process all pending buffer dones
8478 while (pending_bd_q.m_size) {
8479 pending_bd_q.pop_entry(&p1,&p2,&ident);
8480 switch (ident) {
8481 case OMX_COMPONENT_GENERATE_EBD:
8482 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008483 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008484 omx_report_error ();
8485 }
8486 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008487
Arun Menon906de572013-06-18 17:01:40 -07008488 case OMX_COMPONENT_GENERATE_FBD:
8489 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008490 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008491 omx_report_error ();
8492 }
8493 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008494 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008495 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008496}
8497
8498void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8499{
Arun Menon906de572013-06-18 17:01:40 -07008500 OMX_U32 new_frame_interval = 0;
8501 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8502 && llabs(act_timestamp - prev_ts) > 2000) {
Ashray Kulkarni6ecd0372015-09-02 17:51:20 -07008503 new_frame_interval = client_set_fps ? frm_int : (act_timestamp - prev_ts) > 0 ?
8504 llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual);
Arun Menond9e49f82014-04-23 18:50:26 -07008505 if (new_frame_interval != frm_int || frm_int == 0) {
Arun Menon906de572013-06-18 17:01:40 -07008506 frm_int = new_frame_interval;
8507 if (frm_int) {
8508 drv_ctx.frame_rate.fps_numerator = 1e6;
8509 drv_ctx.frame_rate.fps_denominator = frm_int;
8510 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8511 frm_int, drv_ctx.frame_rate.fps_numerator /
8512 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008513
Arun Menon906de572013-06-18 17:01:40 -07008514 /* We need to report the difference between this FBD and the previous FBD
8515 * back to the driver for clock scaling purposes. */
8516 struct v4l2_outputparm oparm;
8517 /*XXX: we're providing timing info as seconds per frame rather than frames
8518 * per second.*/
8519 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8520 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008521
Arun Menon906de572013-06-18 17:01:40 -07008522 struct v4l2_streamparm sparm;
8523 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8524 sparm.parm.output = oparm;
8525 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8526 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8527 performance might be affected");
8528 }
8529
8530 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008531 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008532 }
Arun Menon906de572013-06-18 17:01:40 -07008533 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008534}
8535
8536void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8537{
Arun Menon906de572013-06-18 17:01:40 -07008538 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8539 prev_ts = act_timestamp;
Ashray Kulkarni6ecd0372015-09-02 17:51:20 -07008540 prev_ts_actual = act_timestamp;
Arun Menon906de572013-06-18 17:01:40 -07008541 rst_prev_ts = false;
8542 } else if (VALID_TS(prev_ts)) {
8543 bool codec_cond = (drv_ctx.timestamp_adjust)?
Ashray Kulkarni6ecd0372015-09-02 17:51:20 -07008544 (!VALID_TS(act_timestamp) || act_timestamp < prev_ts_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) :
8545 (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual);
8546 prev_ts_actual = act_timestamp; //unadjusted previous timestamp
Arun Menon906de572013-06-18 17:01:40 -07008547 if (frm_int > 0 && codec_cond) {
8548 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8549 act_timestamp = prev_ts + frm_int;
8550 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8551 prev_ts = act_timestamp;
Leena Winterrowdd139fdc2014-08-05 18:04:25 -07008552 } else {
8553 if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
8554 // ensure that timestamps can never step backwards when in display order
8555 act_timestamp = prev_ts;
8556 }
Arun Menon906de572013-06-18 17:01:40 -07008557 set_frame_rate(act_timestamp);
Leena Winterrowdd139fdc2014-08-05 18:04:25 -07008558 }
Arun Menon906de572013-06-18 17:01:40 -07008559 } else if (frm_int > 0) // In this case the frame rate was set along
8560 { // with the port definition, start ts with 0
8561 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8562 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008563 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008564}
8565
8566void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8567{
Arun Menon906de572013-06-18 17:01:40 -07008568 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8569 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308570 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008571 OMX_U32 frame_rate = 0;
8572 int consumed_len = 0;
8573 OMX_U32 num_MB_in_frame;
8574 OMX_U32 recovery_sei_flags = 1;
8575 int enable = 0;
Arun Menon7b6fd642014-02-13 16:48:36 -08008576
Arun Menon906de572013-06-18 17:01:40 -07008577 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008578 if (buf_index >= drv_ctx.extradata_info.count) {
8579 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8580 buf_index, drv_ctx.extradata_info.count);
8581 return;
8582 }
Arun Menon906de572013-06-18 17:01:40 -07008583 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8584 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8585 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308586
Arun Menon906de572013-06-18 17:01:40 -07008587 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308588 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008589 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008590 }
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308591
8592 if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
8593 DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
8594 p_extra = NULL;
8595 return;
8596 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308597 if (!secure_mode)
8598 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008599 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308600 else
8601 p_extra = m_other_extradata;
8602
Arun Menon906de572013-06-18 17:01:40 -07008603 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308604 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
8605 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
Arun Menon906de572013-06-18 17:01:40 -07008606 p_extra = NULL;
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308607 return;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008608 }
Arun Menon906de572013-06-18 17:01:40 -07008609 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008610 if (data && p_extra) {
Arun Menon906de572013-06-18 17:01:40 -07008611 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8612 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308613 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008614 DEBUG_PRINT_LOW("Invalid extra data size");
8615 break;
8616 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308617 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008618 switch ((unsigned long)data->eType) {
8619 case EXTRADATA_INTERLACE_VIDEO:
8620 struct msm_vidc_interlace_payload *payload;
8621 payload = (struct msm_vidc_interlace_payload *)data->data;
Arun Menon7b6fd642014-02-13 16:48:36 -08008622 if (payload) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008623 enable = 1;
Arun Menon7b6fd642014-02-13 16:48:36 -08008624 switch (payload->format) {
8625 case INTERLACE_FRAME_PROGRESSIVE:
8626 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8627 enable = 0;
8628 break;
8629 case INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
8630 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8631 break;
8632 case INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
8633 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
8634 break;
8635 default:
8636 DEBUG_PRINT_LOW("default case - set interlace to topfield");
8637 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8638 }
Arun Menon906de572013-06-18 17:01:40 -07008639 }
8640 if (m_enable_android_native_buffers)
8641 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8642 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308643 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon7b6fd642014-02-13 16:48:36 -08008644 append_interlace_extradata(p_extra, payload->format,
8645 p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
Arun Menon906de572013-06-18 17:01:40 -07008646 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8647 }
8648 break;
8649 case EXTRADATA_FRAME_RATE:
8650 struct msm_vidc_framerate_payload *frame_rate_payload;
8651 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8652 frame_rate = frame_rate_payload->frame_rate;
8653 break;
8654 case EXTRADATA_TIMESTAMP:
8655 struct msm_vidc_ts_payload *time_stamp_payload;
8656 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308657 time_stamp = time_stamp_payload->timestamp_lo;
8658 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8659 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008660 break;
8661 case EXTRADATA_NUM_CONCEALED_MB:
8662 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8663 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8664 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8665 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8666 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8667 break;
8668 case EXTRADATA_INDEX:
8669 int *etype;
8670 etype = (int *)(data->data);
8671 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8672 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8673 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8674 if (aspect_ratio_payload) {
8675 ((struct vdec_output_frameinfo *)
8676 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8677 ((struct vdec_output_frameinfo *)
8678 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8679 }
8680 }
8681 break;
8682 case EXTRADATA_RECOVERY_POINT_SEI:
8683 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8684 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8685 recovery_sei_flags = recovery_sei_payload->flags;
8686 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8687 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008688 DEBUG_PRINT_HIGH("");
8689 DEBUG_PRINT_HIGH("***************************************************");
8690 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8691 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008692 }
8693 break;
8694 case EXTRADATA_PANSCAN_WINDOW:
8695 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8696 break;
8697 case EXTRADATA_MPEG2_SEQDISP:
8698 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8699 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8700 if (seqdisp_payload) {
8701 m_disp_hor_size = seqdisp_payload->disp_width;
8702 m_disp_vert_size = seqdisp_payload->disp_height;
8703 }
8704 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308705 case EXTRADATA_S3D_FRAME_PACKING:
8706 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8707 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308708 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308709 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8710 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8711 }
8712 break;
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008713 case EXTRADATA_FRAME_QP:
8714 struct msm_vidc_frame_qp_payload *qp_payload;
8715 qp_payload = (struct msm_vidc_frame_qp_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308716 if (client_extradata & OMX_QP_EXTRADATA) {
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008717 append_qp_extradata(p_extra, qp_payload);
8718 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8719 }
8720 break;
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008721 case EXTRADATA_FRAME_BITS_INFO:
8722 struct msm_vidc_frame_bits_info_payload *bits_info_payload;
8723 bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)data->data;
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308724 if (client_extradata & OMX_BITSINFO_EXTRADATA) {
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008725 append_bitsinfo_extradata(p_extra, bits_info_payload);
8726 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8727 }
8728 break;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008729 case EXTRADATA_STREAM_USERDATA:
Pushkaraj Patil74b2eaf2014-06-13 17:07:50 +05308730 if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008731 append_user_extradata(p_extra, data);
8732 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8733 }
8734 break;
Arun Menon906de572013-06-18 17:01:40 -07008735 default:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008736 DEBUG_PRINT_LOW("Unrecognized extradata");
Arun Menon906de572013-06-18 17:01:40 -07008737 goto unrecognized_extradata;
8738 }
8739 consumed_len += data->nSize;
8740 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8741 }
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308742 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008743 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8744 append_frame_info_extradata(p_extra,
8745 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308746 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008747 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008748 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008749 }
8750 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008751unrecognized_extradata:
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008752 if (client_extradata && p_extra) {
8753 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Arun Menon906de572013-06-18 17:01:40 -07008754 append_terminator_extradata(p_extra);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008755 }
8756
Arun Menonfd723932014-05-30 17:56:31 -07008757 if (secure_mode && p_extradata && m_other_extradata) {
Srinu Gorle2eb94e42014-02-14 13:37:40 +05308758 struct vdec_output_frameinfo *ptr_extradatabuff = NULL;
8759 memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
8760 ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
8761 ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
8762 ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
8763 }
Arun Menon906de572013-06-18 17:01:40 -07008764 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008765}
8766
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008767OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008768 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008769{
Arun Menon906de572013-06-18 17:01:40 -07008770 OMX_ERRORTYPE ret = OMX_ErrorNone;
8771 struct v4l2_control control;
8772 if (m_state != OMX_StateLoaded) {
8773 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8774 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008775 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008776 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008777 client_extradata, requested_extradata, enable, is_internal);
8778
8779 if (!is_internal) {
8780 if (enable)
8781 client_extradata |= requested_extradata;
8782 else
8783 client_extradata = client_extradata & ~requested_extradata;
8784 }
8785
8786 if (enable) {
8787 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8788 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8789 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8790 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8791 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008792 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008793 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308794 }
8795 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008796 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8797 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8798 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008799 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008800 }
8801 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8802 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8803 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008804 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008805 }
8806 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8807 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8808 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008809 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008810 }
8811 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8812 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8813 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008814 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008815 }
8816 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8817 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8818 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008819 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008820 }
8821 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8822 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8823 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8824 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008825 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008826 }
8827 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308828 }
8829 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008830 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8831 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8832 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008833 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008834 }
8835 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308836 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8837 if (output_capability == V4L2_PIX_FMT_H264) {
8838 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8839 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8840 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8841 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8842 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8843 }
8844 } else {
8845 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8846 }
8847 }
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008848 if (requested_extradata & OMX_QP_EXTRADATA) {
8849 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8850 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
8851 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8852 DEBUG_PRINT_HIGH("Failed to set QP extradata");
8853 }
8854 }
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08008855 if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
8856 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8857 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
8858 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8859 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
8860 }
8861 }
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08008862 if (requested_extradata & OMX_EXTNUSER_EXTRADATA) {
8863 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8864 control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
8865 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8866 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
8867 }
8868 }
Arun Menon906de572013-06-18 17:01:40 -07008869 }
8870 ret = get_buffer_req(&drv_ctx.op_buf);
8871 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008872}
8873
8874OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8875{
Arun Menon906de572013-06-18 17:01:40 -07008876 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8877 OMX_U8 *data_ptr = extra->data, data = 0;
8878 while (byte_count < extra->nDataSize) {
8879 data = *data_ptr;
8880 while (data) {
8881 num_MB += (data&0x01);
8882 data >>= 1;
8883 }
8884 data_ptr++;
8885 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008886 }
Arun Menon906de572013-06-18 17:01:40 -07008887 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8888 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8889 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008890}
8891
8892void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8893{
Arun Menon906de572013-06-18 17:01:40 -07008894 if (!m_debug_extradata)
8895 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008896
8897 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308898 "============== Extra Data ==============\n"
8899 " Size: %lu\n"
8900 " Version: %lu\n"
8901 " PortIndex: %lu\n"
8902 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008903 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008904 extra->nSize, extra->nVersion.nVersion,
8905 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008906
Arun Menon906de572013-06-18 17:01:40 -07008907 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8908 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8909 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308910 "------ Interlace Format ------\n"
8911 " Size: %lu\n"
8912 " Version: %lu\n"
8913 " PortIndex: %lu\n"
8914 " Is Interlace Format: %d\n"
8915 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008916 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008917 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8918 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8919 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8920 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8921
8922 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308923 "-------- Frame Format --------\n"
8924 " Picture Type: %d\n"
8925 " Interlace Type: %d\n"
8926 " Pan Scan Total Frame Num: %lu\n"
8927 " Concealed Macro Blocks: %lu\n"
8928 " frame rate: %lu\n"
8929 " Time Stamp: %llu\n"
8930 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008931 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008932 fminfo->ePicType,
8933 fminfo->interlaceType,
8934 fminfo->panScan.numWindows,
8935 fminfo->nConcealedMacroblocks,
8936 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308937 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008938 fminfo->aspectRatio.aspectRatioX,
8939 fminfo->aspectRatio.aspectRatioY);
8940
8941 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8942 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008943 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308944 " Pan Scan Frame Num: %lu\n"
8945 " Rectangle x: %ld\n"
8946 " Rectangle y: %ld\n"
8947 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008948 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008949 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8950 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8951 }
8952
8953 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308954 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8955 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8956 DEBUG_PRINT_HIGH(
8957 "------------------ Framepack Format ----------\n"
8958 " id: %lu \n"
8959 " cancel_flag: %lu \n"
8960 " type: %lu \n"
8961 " quincunx_sampling_flagFormat: %lu \n"
8962 " content_interpretation_type: %lu \n"
8963 " content_interpretation_type: %lu \n"
8964 " spatial_flipping_flag: %lu \n"
8965 " frame0_flipped_flag: %lu \n"
8966 " field_views_flag: %lu \n"
8967 " current_frame_is_frame0_flag: %lu \n"
8968 " frame0_self_contained_flag: %lu \n"
8969 " frame1_self_contained_flag: %lu \n"
8970 " frame0_grid_position_x: %lu \n"
8971 " frame0_grid_position_y: %lu \n"
8972 " frame1_grid_position_x: %lu \n"
8973 " frame1_grid_position_y: %lu \n"
8974 " reserved_byte: %lu \n"
8975 " repetition_period: %lu \n"
8976 " extension_flag: %lu \n"
8977 "================== End of Framepack ===========",
8978 framepack->id,
8979 framepack->cancel_flag,
8980 framepack->type,
8981 framepack->quincunx_sampling_flag,
8982 framepack->content_interpretation_type,
8983 framepack->spatial_flipping_flag,
8984 framepack->frame0_flipped_flag,
8985 framepack->field_views_flag,
8986 framepack->current_frame_is_frame0_flag,
8987 framepack->frame0_self_contained_flag,
8988 framepack->frame1_self_contained_flag,
8989 framepack->frame0_grid_position_x,
8990 framepack->frame0_grid_position_y,
8991 framepack->frame1_grid_position_x,
8992 framepack->frame1_grid_position_y,
8993 framepack->reserved_byte,
8994 framepack->repetition_period,
8995 framepack->extension_flag);
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08008996 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
8997 OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
8998 DEBUG_PRINT_HIGH(
8999 "---- QP (Frame quantization parameter) ----\n"
9000 " Frame QP: %lu \n"
9001 "================ End of QP ================\n",
9002 qp->nQP);
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08009003 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
9004 OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)extra->data;
9005 DEBUG_PRINT_HIGH(
9006 "--------- Input bits information --------\n"
9007 " Header bits: %lu \n"
9008 " Frame bits: %lu \n"
9009 "===== End of Input bits information =====\n",
9010 bits->header_bits, bits->frame_bits);
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009011 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
9012 OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)extra->data;
9013 OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
9014 OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
9015 OMX_U32 i = 0;
9016 DEBUG_PRINT_HIGH(
9017 "-------------- Userdata -------------\n"
9018 " Stream userdata type: %d\n"
9019 " userdata size: %d\n"
9020 " STREAM_USERDATA:",
9021 userdata->type, userdata_size);
9022 for (i = 0; i < userdata_size; i+=4) {
9023 DEBUG_PRINT_HIGH(" %x %x %x %x",
9024 data_ptr[i], data_ptr[i+1],
9025 data_ptr[i+2], data_ptr[i+3]);
9026 }
9027 DEBUG_PRINT_HIGH(
9028 "=========== End of Userdata ===========");
Arun Menon906de572013-06-18 17:01:40 -07009029 } else if (extra->eType == OMX_ExtraDataNone) {
9030 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
9031 } else {
9032 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07009033 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009034}
9035
9036void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon7b6fd642014-02-13 16:48:36 -08009037 OMX_U32 interlaced_format_type, bool is_mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009038{
Arun Menon906de572013-06-18 17:01:40 -07009039 OMX_STREAMINTERLACEFORMAT *interlace_format;
Arun Menon7b6fd642014-02-13 16:48:36 -08009040
Arun Menon906de572013-06-18 17:01:40 -07009041 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
9042 return;
9043 }
9044 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
9045 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9046 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9047 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
9048 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9049 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
9050 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
9051 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
9052 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
Arun Menon7b6fd642014-02-13 16:48:36 -08009053
9054 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
Arun Menon906de572013-06-18 17:01:40 -07009055 interlace_format->bInterlaceFormat = OMX_FALSE;
9056 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
9057 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08009058 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009059 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08009060 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009061 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon7b6fd642014-02-13 16:48:36 -08009062 } else if ((interlaced_format_type == INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009063 interlace_format->bInterlaceFormat = OMX_TRUE;
Arun Menon7b6fd642014-02-13 16:48:36 -08009064 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07009065 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07009066 } else {
9067 interlace_format->bInterlaceFormat = OMX_TRUE;
9068 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
9069 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
9070 }
9071 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009072}
9073
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009074void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07009075 struct vdec_aspectratioinfo *aspect_ratio_info,
9076 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009077{
Arun Menon906de572013-06-18 17:01:40 -07009078 m_extradata = frame_info;
9079 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
9080 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309081 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07009082 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009083}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009084
9085void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07009086 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309087 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08009088 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07009089{
Arun Menon906de572013-06-18 17:01:40 -07009090 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
9091 struct msm_vidc_panscan_window *panscan_window;
9092 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009093 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009094 }
Arun Menon906de572013-06-18 17:01:40 -07009095 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
9096 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9097 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9098 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
9099 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
9100 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
9101 switch (picture_type) {
9102 case PICTURE_TYPE_I:
9103 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
9104 break;
9105 case PICTURE_TYPE_P:
9106 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
9107 break;
9108 case PICTURE_TYPE_B:
9109 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
9110 break;
9111 default:
9112 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
9113 }
9114 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
9115 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
9116 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
9117 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
9118 else
9119 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
9120 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
9121 frame_info->nConcealedMacroblocks = num_conceal_mb;
9122 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05309123 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07009124 frame_info->panScan.numWindows = 0;
9125 if (output_capability == V4L2_PIX_FMT_MPEG2) {
9126 if (m_disp_hor_size && m_disp_vert_size) {
9127 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
9128 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
Pushkaraj Patil5e6ebd92014-03-10 10:29:14 +05309129 } else {
9130 frame_info->displayAspectRatio.displayHorizontalSize = 0;
9131 frame_info->displayAspectRatio.displayVerticalSize = 0;
Arun Menon906de572013-06-18 17:01:40 -07009132 }
9133 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07009134
Arun Menon906de572013-06-18 17:01:40 -07009135 if (panscan_payload) {
9136 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
9137 panscan_window = &panscan_payload->wnd[0];
9138 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
9139 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
9140 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
9141 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
9142 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
9143 panscan_window++;
9144 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08009145 }
Arun Menon906de572013-06-18 17:01:40 -07009146 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
9147 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009148}
9149
9150void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9151{
Arun Menon906de572013-06-18 17:01:40 -07009152 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
9153 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
9154 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9155 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9156 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
9157 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
9158 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
9159 *portDefn = m_port_def;
9160 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009161 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07009162 portDefn->format.video.nFrameWidth,
9163 portDefn->format.video.nStride,
9164 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009165}
9166
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05309167void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9168 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
9169{
9170 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
9171 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
9172 DEBUG_PRINT_ERROR("frame packing size mismatch");
9173 return;
9174 }
9175 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
9176 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9177 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9178 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
9179 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9180 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
9181 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
9182 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
9183 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9184 memcpy(&framepack->id, s3d_frame_packing_payload,
9185 sizeof(struct msm_vidc_s3d_frame_packing_payload));
9186 memcpy(&m_frame_pack_arrangement, framepack,
9187 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
9188 print_debug_extradata(extra);
9189}
9190
Jorge Solano Altamiranob10850d2014-01-08 11:17:58 -08009191void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9192 struct msm_vidc_frame_qp_payload *qp_payload)
9193{
9194 OMX_QCOM_EXTRADATA_QP * qp = NULL;
9195 if (!qp_payload) {
9196 DEBUG_PRINT_ERROR("QP payload is NULL");
9197 return;
9198 }
9199 extra->nSize = OMX_QP_EXTRADATA_SIZE;
9200 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9201 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9202 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
9203 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
9204 qp = (OMX_QCOM_EXTRADATA_QP *)extra->data;
9205 qp->nQP = qp_payload->frame_qp;
9206 print_debug_extradata(extra);
9207}
9208
Jorge Solano Altamirano54338452014-01-08 11:04:57 -08009209void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9210 struct msm_vidc_frame_bits_info_payload *bits_payload)
9211{
9212 OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
9213 if (!bits_payload) {
9214 DEBUG_PRINT_ERROR("bits info payload is NULL");
9215 return;
9216 }
9217 extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
9218 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9219 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9220 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
9221 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
9222 bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)extra->data;
9223 bits->frame_bits = bits_payload->frame_bits;
9224 bits->header_bits = bits_payload->header_bits;
9225 print_debug_extradata(extra);
9226}
9227
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009228void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
9229 OMX_OTHER_EXTRADATATYPE *p_user)
9230{
9231 int userdata_size = 0;
9232 struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
9233 userdata_payload =
9234 (struct msm_vidc_stream_userdata_payload *)p_user->data;
9235 userdata_size = p_user->nDataSize;
Deva Ramasubramanian2ebfed32014-04-24 13:34:24 -07009236 extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + p_user->nSize;
Jorge Solano Altamirano1ae09be2014-01-16 12:21:52 -08009237 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9238 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9239 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
9240 extra->nDataSize = userdata_size;
9241 if (extra->data && p_user->data && extra->nDataSize)
9242 memcpy(extra->data, p_user->data, extra->nDataSize);
9243 print_debug_extradata(extra);
9244}
9245
Shalaj Jain273b3e02012-06-22 19:08:03 -07009246void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
9247{
Arun Menon906de572013-06-18 17:01:40 -07009248 if (!client_extradata) {
9249 return;
9250 }
9251 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
9252 extra->nVersion.nVersion = OMX_SPEC_VERSION;
9253 extra->eType = OMX_ExtraDataNone;
9254 extra->nDataSize = 0;
9255 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009256
Arun Menon906de572013-06-18 17:01:40 -07009257 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009258}
9259
9260OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
9261{
Arun Menon906de572013-06-18 17:01:40 -07009262 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9263 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009264 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07009265 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009266 }
Arun Menon906de572013-06-18 17:01:40 -07009267 if (m_desc_buffer_ptr == NULL) {
9268 m_desc_buffer_ptr = (desc_buffer_hdr*) \
9269 calloc( (sizeof(desc_buffer_hdr)),
9270 drv_ctx.ip_buf.actualcount);
9271 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009272 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009273 return OMX_ErrorInsufficientResources;
9274 }
9275 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009276
Arun Menon906de572013-06-18 17:01:40 -07009277 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
9278 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009279 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07009280 return OMX_ErrorInsufficientResources;
9281 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009282
Arun Menon906de572013-06-18 17:01:40 -07009283 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009284}
9285
9286void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
9287{
Arun Menon906de572013-06-18 17:01:40 -07009288 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
9289 if (m_demux_entries < 8192) {
9290 m_demux_offsets[m_demux_entries++] = address_offset;
9291 }
9292 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009293}
9294
9295void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
9296{
Arun Menon906de572013-06-18 17:01:40 -07009297 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
9298 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
9299 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009300
Arun Menon906de572013-06-18 17:01:40 -07009301 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009302
Arun Menon906de572013-06-18 17:01:40 -07009303 while (index < bytes_to_parse) {
9304 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9305 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
9306 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
9307 (buf[index+2] == 0x01)) ) {
9308 //Found start code, insert address offset
9309 insert_demux_addr_offset(index);
9310 if (buf[index+2] == 0x01) // 3 byte start code
9311 index += 3;
9312 else //4 byte start code
9313 index += 4;
9314 } else
9315 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009316 }
Arun Menon906de572013-06-18 17:01:40 -07009317 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
9318 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009319}
9320
9321OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
9322{
Arun Menon906de572013-06-18 17:01:40 -07009323 //fix this, handle 3 byte start code, vc1 terminator entry
9324 OMX_U8 *p_demux_data = NULL;
9325 OMX_U32 desc_data = 0;
9326 OMX_U32 start_addr = 0;
9327 OMX_U32 nal_size = 0;
9328 OMX_U32 suffix_byte = 0;
9329 OMX_U32 demux_index = 0;
9330 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009331
Arun Menon906de572013-06-18 17:01:40 -07009332 if (m_desc_buffer_ptr == NULL) {
9333 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
9334 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009335 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07009336
Arun Menon906de572013-06-18 17:01:40 -07009337 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
9338 if (buffer_index > drv_ctx.ip_buf.actualcount) {
9339 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
9340 return OMX_ErrorBadParameter;
9341 }
9342
9343 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
9344
9345 if ( ((OMX_U8*)p_demux_data == NULL) ||
9346 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
9347 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
9348 return OMX_ErrorBadParameter;
9349 } else {
9350 for (; demux_index < m_demux_entries; demux_index++) {
9351 desc_data = 0;
9352 start_addr = m_demux_offsets[demux_index];
9353 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
9354 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
9355 } else {
9356 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
9357 }
9358 if (demux_index < (m_demux_entries - 1)) {
9359 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
9360 } else {
9361 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
9362 }
9363 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
9364 (void *)start_addr,
9365 suffix_byte,
9366 nal_size,
9367 demux_index);
9368 desc_data = (start_addr >> 3) << 1;
9369 desc_data |= (start_addr & 7) << 21;
9370 desc_data |= suffix_byte << 24;
9371
9372 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9373 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
9374 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9375 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9376
9377 p_demux_data += 16;
9378 }
9379 if (codec_type_parse == CODEC_TYPE_VC1) {
9380 DEBUG_PRINT_LOW("VC1 terminator entry");
9381 desc_data = 0;
9382 desc_data = 0x82 << 24;
9383 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
9384 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
9385 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
9386 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
9387 p_demux_data += 16;
9388 m_demux_entries++;
9389 }
9390 //Add zero word to indicate end of descriptors
9391 memset(p_demux_data, 0, sizeof(OMX_U32));
9392
9393 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
9394 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
9395 }
9396 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
9397 m_demux_entries = 0;
9398 DEBUG_PRINT_LOW("Demux table complete!");
9399 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009400}
9401
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08009402OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07009403{
Arun Menon906de572013-06-18 17:01:40 -07009404 OMX_ERRORTYPE err = OMX_ErrorNone;
9405 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9406 if (iDivXDrmDecrypt) {
9407 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9408 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009409 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07009410 delete iDivXDrmDecrypt;
9411 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07009412 }
9413 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009414 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07009415 err = OMX_ErrorUndefined;
9416 }
9417 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07009418}
Shalaj Jain273b3e02012-06-22 19:08:03 -07009419
Vinay Kaliada4f4422013-01-09 10:45:03 -08009420omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9421{
Arun Menon906de572013-06-18 17:01:40 -07009422 enabled = false;
9423 omx = NULL;
9424 init_members();
9425 ColorFormat = OMX_COLOR_FormatMax;
Praveen Chavandb7776f2014-02-06 18:17:25 -08009426 dest_format = YCbCr420P;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009427}
9428
9429void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9430{
Arun Menon906de572013-06-18 17:01:40 -07009431 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009432}
9433
Arun Menon906de572013-06-18 17:01:40 -07009434void omx_vdec::allocate_color_convert_buf::init_members()
9435{
9436 allocated_count = 0;
9437 buffer_size_req = 0;
9438 buffer_alignment_req = 0;
9439 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9440 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9441 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9442 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009443#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009444 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08009445#endif
Arun Menon906de572013-06-18 17:01:40 -07009446 for (int i = 0; i < MAX_COUNT; i++)
9447 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009448}
9449
Arun Menon906de572013-06-18 17:01:40 -07009450omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9451{
9452 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08009453}
9454
9455bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9456{
Arun Menon906de572013-06-18 17:01:40 -07009457 bool status = true;
9458 unsigned int src_size = 0, destination_size = 0;
9459 OMX_COLOR_FORMATTYPE drv_color_format;
9460 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009461 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009462 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009463 }
Arun Menon906de572013-06-18 17:01:40 -07009464 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009465 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07009466 return status;
9467 }
9468 pthread_mutex_lock(&omx->c_lock);
9469 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
9470 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009471 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07009472 status = false;
9473 goto fail_update_buf_req;
9474 }
9475 c2d.close();
9476 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9477 omx->drv_ctx.video_resolution.frame_width,
Praveen Chavandb7776f2014-02-06 18:17:25 -08009478 NV12_128m,dest_format);
Arun Menon906de572013-06-18 17:01:40 -07009479 if (status) {
9480 status = c2d.get_buffer_size(C2D_INPUT,src_size);
9481 if (status)
9482 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9483 }
9484 if (status) {
9485 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9486 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009487 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07009488 "driver size %d destination size %d",
9489 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9490 status = false;
9491 c2d.close();
9492 buffer_size_req = 0;
9493 } else {
9494 buffer_size_req = destination_size;
9495 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9496 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9497 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9498 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9499 }
9500 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009501fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07009502 pthread_mutex_unlock(&omx->c_lock);
9503 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009504}
9505
9506bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07009507 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009508{
Arun Menon906de572013-06-18 17:01:40 -07009509 bool status = true;
9510 OMX_COLOR_FORMATTYPE drv_color_format;
9511 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009512 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07009513 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009514 }
Arun Menon906de572013-06-18 17:01:40 -07009515 pthread_mutex_lock(&omx->c_lock);
9516 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9517 drv_color_format = (OMX_COLOR_FORMATTYPE)
9518 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9519 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009520 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07009521 status = false;
9522 }
9523 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009524 DEBUG_PRINT_LOW("Enabling C2D");
Praveen Chavandb7776f2014-02-06 18:17:25 -08009525 if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
9526 (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009527 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009528 status = false;
9529 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009530 ColorFormat = dest_color_format;
9531 dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
9532 YCbCr420P : YCbCr420SP;
Arun Menon906de572013-06-18 17:01:40 -07009533 if (enabled)
9534 c2d.destroy();
9535 enabled = false;
9536 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009537 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07009538 status = false;
9539 } else
9540 enabled = true;
9541 }
9542 } else {
9543 if (enabled)
9544 c2d.destroy();
9545 enabled = false;
9546 }
9547 pthread_mutex_unlock(&omx->c_lock);
9548 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009549}
9550
9551OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9552{
Arun Menon906de572013-06-18 17:01:40 -07009553 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009554 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009555 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009556 }
Arun Menon906de572013-06-18 17:01:40 -07009557 if (!enabled)
9558 return omx->m_out_mem_ptr;
9559 return m_out_mem_ptr_client;
9560}
9561
9562 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9563(OMX_BUFFERHEADERTYPE *bufadd)
9564{
9565 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009566 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009567 return NULL;
9568 }
9569 if (!enabled)
9570 return bufadd;
9571
9572 unsigned index = 0;
9573 index = bufadd - omx->m_out_mem_ptr;
9574 if (index < omx->drv_ctx.op_buf.actualcount) {
9575 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9576 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9577 bool status;
9578 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9579 pthread_mutex_lock(&omx->c_lock);
9580 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9581 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9582 pmem_baseaddress[index], pmem_baseaddress[index]);
Arun Menon906de572013-06-18 17:01:40 -07009583 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009584 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009585 m_out_mem_ptr_client[index].nFilledLen = 0;
Leena Winterrowd270a7042014-09-30 13:05:55 -07009586 pthread_mutex_unlock(&omx->c_lock);
Arun Menon906de572013-06-18 17:01:40 -07009587 return &m_out_mem_ptr_client[index];
Praveen Chavan6d6b7252014-09-15 17:05:54 -07009588 } else {
9589 unsigned int filledLen = 0;
9590 c2d.get_output_filled_length(filledLen);
9591 m_out_mem_ptr_client[index].nFilledLen = filledLen;
Arun Menon906de572013-06-18 17:01:40 -07009592 }
Leena Winterrowd270a7042014-09-30 13:05:55 -07009593 pthread_mutex_unlock(&omx->c_lock);
Arun Menon906de572013-06-18 17:01:40 -07009594 } else
9595 m_out_mem_ptr_client[index].nFilledLen = 0;
9596 return &m_out_mem_ptr_client[index];
9597 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009598 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009599 return NULL;
9600}
9601
9602 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9603(OMX_BUFFERHEADERTYPE *bufadd)
9604{
9605 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009606 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009607 return NULL;
9608 }
9609 if (!enabled)
9610 return bufadd;
9611 unsigned index = 0;
9612 index = bufadd - m_out_mem_ptr_client;
9613 if (index < omx->drv_ctx.op_buf.actualcount) {
9614 return &omx->m_out_mem_ptr[index];
9615 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009616 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009617 return NULL;
9618}
9619 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9620(unsigned int &buffer_size)
9621{
9622 bool status = true;
9623 pthread_mutex_lock(&omx->c_lock);
9624 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009625 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009626 else {
9627 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009628 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009629 status = false;
9630 goto fail_get_buffer_size;
9631 }
9632 }
9633 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9634 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9635 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9636 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009637fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009638 pthread_mutex_unlock(&omx->c_lock);
9639 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009640}
9641OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009642 OMX_BUFFERHEADERTYPE *bufhdr)
9643{
9644 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009645
Arun Menon906de572013-06-18 17:01:40 -07009646 if (!enabled)
9647 return omx->free_output_buffer(bufhdr);
9648 if (enabled && omx->is_component_secure())
9649 return OMX_ErrorNone;
9650 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009651 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009652 return OMX_ErrorBadParameter;
9653 }
9654 index = bufhdr - m_out_mem_ptr_client;
9655 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009656 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009657 return OMX_ErrorBadParameter;
9658 }
9659 if (pmem_fd[index] > 0) {
9660 munmap(pmem_baseaddress[index], buffer_size_req);
9661 close(pmem_fd[index]);
9662 }
9663 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009664#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009665 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009666#endif
Arun Menon906de572013-06-18 17:01:40 -07009667 m_heap_ptr[index].video_heap_ptr = NULL;
9668 if (allocated_count > 0)
9669 allocated_count--;
9670 else
9671 allocated_count = 0;
9672 if (!allocated_count) {
9673 pthread_mutex_lock(&omx->c_lock);
9674 c2d.close();
9675 init_members();
9676 pthread_mutex_unlock(&omx->c_lock);
9677 }
9678 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009679}
9680
9681OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009682 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009683{
Arun Menon906de572013-06-18 17:01:40 -07009684 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9685 if (!enabled) {
9686 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9687 return eRet;
9688 }
9689 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009690 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009691 omx->is_component_secure());
9692 return OMX_ErrorUnsupportedSetting;
9693 }
9694 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009695 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9696 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009697 buffer_size_req,bytes);
9698 return OMX_ErrorBadParameter;
9699 }
9700 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009701 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009702 return OMX_ErrorInsufficientResources;
9703 }
9704 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9705 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9706 port,appData,omx->drv_ctx.op_buf.buffer_size);
9707 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009708 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009709 return eRet;
9710 }
9711 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309712 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009713 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009714 (temp_bufferHdr - omx->m_out_mem_ptr));
9715 return OMX_ErrorUndefined;
9716 }
9717 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009718#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009719 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9720 buffer_size_req,buffer_alignment_req,
9721 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9722 0);
9723 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9724 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009725 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009726 return OMX_ErrorInsufficientResources;
9727 }
9728 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9729 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009730
Arun Menon906de572013-06-18 17:01:40 -07009731 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009732 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009733 close(pmem_fd[i]);
9734 omx->free_ion_memory(&op_buf_ion_info[i]);
9735 return OMX_ErrorInsufficientResources;
9736 }
9737 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9738 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9739 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009740#endif
Arun Menon906de572013-06-18 17:01:40 -07009741 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9742 m_pmem_info_client[i].offset = 0;
9743 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9744 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9745 m_platform_list_client[i].nEntries = 1;
9746 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9747 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9748 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9749 m_out_mem_ptr_client[i].nFilledLen = 0;
9750 m_out_mem_ptr_client[i].nFlags = 0;
9751 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9752 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9753 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9754 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9755 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9756 m_out_mem_ptr_client[i].pAppPrivate = appData;
9757 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009758 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009759 allocated_count++;
9760 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009761}
9762
9763bool omx_vdec::is_component_secure()
9764{
Arun Menon906de572013-06-18 17:01:40 -07009765 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009766}
9767
9768bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9769{
Arun Menon906de572013-06-18 17:01:40 -07009770 bool status = true;
9771 if (!enabled) {
9772 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9773 dest_color_format = (OMX_COLOR_FORMATTYPE)
9774 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9775 else
9776 status = false;
9777 } else {
Praveen Chavandb7776f2014-02-06 18:17:25 -08009778 if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
9779 ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
9780 dest_color_format = ColorFormat;
Arun Menon906de572013-06-18 17:01:40 -07009781 } else
Praveen Chavandb7776f2014-02-06 18:17:25 -08009782 status = false;
Arun Menon906de572013-06-18 17:01:40 -07009783 }
9784 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009785}
Arun Menonbdb80b02013-08-12 17:45:54 -07009786
Arun Menonbdb80b02013-08-12 17:45:54 -07009787void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9788{
9789 int i = 0;
9790 bool buf_present = false;
9791 pthread_mutex_lock(&m_lock);
9792 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9793 //check the buffer fd, offset, uv addr with list contents
9794 //If present increment reference.
9795 if ((out_dynamic_list[i].fd == fd) &&
9796 (out_dynamic_list[i].offset == offset)) {
9797 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009798 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009799 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9800 buf_present = true;
9801 break;
9802 }
9803 }
9804 if (!buf_present) {
9805 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9806 //search for a entry to insert details of the new buffer
9807 if (out_dynamic_list[i].dup_fd == 0) {
9808 out_dynamic_list[i].fd = fd;
9809 out_dynamic_list[i].offset = offset;
9810 out_dynamic_list[i].dup_fd = dup(fd);
9811 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009812 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009813 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9814 break;
9815 }
9816 }
9817 }
9818 pthread_mutex_unlock(&m_lock);
9819}
9820
9821void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9822{
9823 int i = 0;
9824 pthread_mutex_lock(&m_lock);
9825 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9826 //check the buffer fd, offset, uv addr with list contents
9827 //If present decrement reference.
9828 if ((out_dynamic_list[i].fd == fd) &&
9829 (out_dynamic_list[i].offset == offset)) {
9830 out_dynamic_list[i].ref_count--;
9831 if (out_dynamic_list[i].ref_count == 0) {
9832 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009833 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009834 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9835 out_dynamic_list[i].dup_fd = 0;
9836 out_dynamic_list[i].fd = 0;
9837 out_dynamic_list[i].offset = 0;
9838 }
9839 break;
9840 }
9841 }
9842 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009843 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009844 }
9845 pthread_mutex_unlock(&m_lock);
9846}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009847
Arun Menon1fc764f2014-04-17 15:41:27 -07009848OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
9849 unsigned long nMaxFrameHeight)
9850{
9851
9852 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9853 int ret = 0;
9854 unsigned long min_res_buf_count = 0;
9855
9856 eRet = enable_smoothstreaming();
9857 if (eRet != OMX_ErrorNone) {
9858 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
9859 return eRet;
9860 }
9861
9862 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
9863 nMaxFrameWidth,
9864 nMaxFrameHeight);
9865 m_smoothstreaming_mode = true;
9866 m_smoothstreaming_width = nMaxFrameWidth;
9867 m_smoothstreaming_height = nMaxFrameHeight;
9868
9869 //Get upper limit buffer count for min supported resolution
9870 struct v4l2_format fmt;
9871 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9872 fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
9873 fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
9874 fmt.fmt.pix_mp.pixelformat = output_capability;
9875
9876 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9877 if (ret) {
9878 DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
9879 m_decoder_capability.min_height,
9880 m_decoder_capability.min_width);
9881 return OMX_ErrorUnsupportedSetting;
9882 }
9883
9884 eRet = get_buffer_req(&drv_ctx.op_buf);
9885 if (eRet != OMX_ErrorNone) {
9886 DEBUG_PRINT_ERROR("failed to get_buffer_req");
9887 return eRet;
9888 }
9889
9890 min_res_buf_count = drv_ctx.op_buf.mincount;
9891 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
9892 min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
9893
9894 update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
9895 m_smoothstreaming_width, m_smoothstreaming_height);
9896 eRet = is_video_session_supported();
9897 if (eRet != OMX_ErrorNone) {
9898 DEBUG_PRINT_ERROR("video session is not supported");
9899 return eRet;
9900 }
9901
9902 //Get upper limit buffer size for max smooth streaming resolution set
9903 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
9904 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
9905 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
9906 fmt.fmt.pix_mp.pixelformat = output_capability;
9907 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
9908 if (ret) {
9909 DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
9910 return OMX_ErrorUnsupportedSetting;
9911 }
9912
9913 eRet = get_buffer_req(&drv_ctx.op_buf);
9914 if (eRet != OMX_ErrorNone) {
9915 DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
9916 return eRet;
9917 }
9918 DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
9919 drv_ctx.op_buf.buffer_size);
9920
9921 drv_ctx.op_buf.mincount = min_res_buf_count;
9922 drv_ctx.op_buf.actualcount = min_res_buf_count;
9923 eRet = set_buffer_req(&drv_ctx.op_buf);
9924 if (eRet != OMX_ErrorNone) {
9925 DEBUG_PRINT_ERROR("failed to set_buffer_req");
9926 return eRet;
9927 }
9928
9929 eRet = get_buffer_req(&drv_ctx.op_buf);
9930 if (eRet != OMX_ErrorNone) {
9931 DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
9932 return eRet;
9933 }
9934 DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
9935 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size);
9936 return eRet;
9937}
9938
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009939#ifdef _MSM8974_
9940void omx_vdec::send_codec_config() {
9941 if (codec_config_flag) {
9942 unsigned p1 = 0; // Parameter - 1
9943 unsigned p2 = 0; // Parameter - 2
9944 unsigned ident = 0;
9945 pthread_mutex_lock(&m_lock);
9946 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9947 while (m_etb_q.m_size) {
9948 m_etb_q.pop_entry(&p1,&p2,&ident);
9949 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9950 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9951 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9952 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9953 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9954 omx_report_error();
9955 }
9956 } else {
9957 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9958 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9959 }
9960 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9961 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9962 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9963 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9964 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9965 omx_report_error ();
9966 }
9967 } else {
9968 pending_input_buffers++;
9969 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9970 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9971 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9972 }
9973 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9974 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9975 (OMX_BUFFERHEADERTYPE *)p1);
9976 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9977 }
9978 }
9979 pthread_mutex_unlock(&m_lock);
9980 }
9981}
9982#endif
Praveen Chavan09a82b72014-10-18 09:09:45 -07009983
9984//static
9985OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
9986
9987#ifndef FLEXYUV_SUPPORTED
9988 (void)pParam;
9989 return OMX_ErrorUndefined;
9990#else
9991
9992 if (pParam == NULL) {
9993 DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
9994 return OMX_ErrorBadParameter;
9995 }
9996
9997 DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
9998
9999 MediaImage *img = &(params->sMediaImage);
10000 switch(params->eColorFormat) {
10001 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
10002 {
10003 img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
10004 img->mNumPlanes = 3;
10005 // mWidth and mHeight represent the W x H of the largest plane
10006 // In our case, this happens to be the Stride x Scanlines of Y plane
10007 img->mWidth = params->nFrameWidth;
10008 img->mHeight = params->nFrameHeight;
10009 size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
10010 size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
10011 img->mBitDepth = 8;
10012 //Plane 0 (Y)
10013 img->mPlane[MediaImage::Y].mOffset = 0;
10014 img->mPlane[MediaImage::Y].mColInc = 1;
10015 img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
10016 img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
10017 img->mPlane[MediaImage::Y].mVertSubsampling = 1;
10018 //Plane 1 (U)
10019 img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
10020 img->mPlane[MediaImage::U].mColInc = 2; //interleaved UV
10021 img->mPlane[MediaImage::U].mRowInc =
10022 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
10023 img->mPlane[MediaImage::U].mHorizSubsampling = 2;
10024 img->mPlane[MediaImage::U].mVertSubsampling = 2;
10025 //Plane 2 (V)
10026 img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
10027 img->mPlane[MediaImage::V].mColInc = 2; //interleaved UV
10028 img->mPlane[MediaImage::V].mRowInc =
10029 VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
10030 img->mPlane[MediaImage::V].mHorizSubsampling = 2;
10031 img->mPlane[MediaImage::V].mVertSubsampling = 2;
10032 break;
10033 }
10034
10035 case OMX_COLOR_FormatYUV420Planar:
10036 case OMX_COLOR_FormatYUV420SemiPlanar:
10037 // We need not describe the standard OMX linear formats as these are
10038 // understood by client. Fail this deliberately to let client fill-in
10039 return OMX_ErrorUnsupportedSetting;
10040
10041 default:
10042 // Rest all formats which are non-linear cannot be described
10043 DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
10044 img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
10045 return OMX_ErrorNone;
10046 };
10047
10048 DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
10049 DEBUG_PRINT_LOW(" FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
10050 DEBUG_PRINT_LOW(" YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
10051 for (size_t i = 0; i < img->mNumPlanes; ++i) {
10052 DEBUG_PRINT_LOW(" Plane[%d] : offset=%d / xStep=%d / yStep = %d",
10053 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
10054 }
10055 return OMX_ErrorNone;
10056#endif //FLEXYUV_SUPPORTED
10057}
10058