blob: a1313e27457ee75822d872c93215db47db1490be [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
42#include <string.h>
43#include <pthread.h>
44#include <sys/prctl.h>
45#include <stdlib.h>
46#include <unistd.h>
47#include <errno.h>
48#include "omx_vdec.h"
49#include <fcntl.h>
50#include <limits.h>
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -070051#include <stdlib.h>
Arun Menonbdb80b02013-08-12 17:45:54 -070052#include <media/hardware/HardwareAPI.h>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080053#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070054
55#ifndef _ANDROID_
56#include <sys/ioctl.h>
57#include <sys/mman.h>
58#endif //_ANDROID_
59
60#ifdef _ANDROID_
61#include <cutils/properties.h>
62#undef USE_EGL_IMAGE_GPU
63#endif
64
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070065#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070066
67#ifdef _ANDROID_
68#include "DivXDrmDecrypt.h"
69#endif //_ANDROID_
70
Arun Menon45346052013-11-13 12:40:08 -080071#ifdef METADATA_FOR_DYNAMIC_MODE
Arun Menon9af783f2013-10-22 12:57:14 -070072#include "QComOMXMetadata.h"
73#endif
74
Shalaj Jain273b3e02012-06-22 19:08:03 -070075#ifdef USE_EGL_IMAGE_GPU
76#include <EGL/egl.h>
77#include <EGL/eglQCOM.h>
78#define EGL_BUFFER_HANDLE_QCOM 0x4F00
79#define EGL_BUFFER_OFFSET_QCOM 0x4F01
80#endif
Vinay Kalia21649b32013-03-18 17:28:07 -070081
Jayasena Sangaraboina51230642013-08-21 18:02:13 -070082#define BUFFER_LOG_LOC "/data/misc/media"
83
Shalaj Jain273b3e02012-06-22 19:08:03 -070084#ifdef OUTPUT_EXTRADATA_LOG
85FILE *outputExtradataFile;
86char ouputextradatafilename [] = "/data/extradata";
87#endif
88
89#define DEFAULT_FPS 30
90#define MAX_INPUT_ERROR DEFAULT_FPS
91#define MAX_SUPPORTED_FPS 120
92
93#define VC1_SP_MP_START_CODE 0xC5000000
94#define VC1_SP_MP_START_CODE_MASK 0xFF000000
95#define VC1_AP_SEQ_START_CODE 0x0F010000
96#define VC1_STRUCT_C_PROFILE_MASK 0xF0
97#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
98#define VC1_SIMPLE_PROFILE 0
99#define VC1_MAIN_PROFILE 1
100#define VC1_ADVANCE_PROFILE 3
101#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
102#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
103#define VC1_STRUCT_C_LEN 4
104#define VC1_STRUCT_C_POS 8
105#define VC1_STRUCT_A_POS 12
106#define VC1_STRUCT_B_POS 24
107#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700108#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700109
110#define MEM_DEVICE "/dev/ion"
111#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
112
113#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700114extern "C" {
115#include<utils/Log.h>
116}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700117#endif//_ANDROID_
118
Vinay Kalia53fa6832012-10-11 17:55:30 -0700119#define SZ_4K 0x1000
120#define SZ_1M 0x100000
121
Shalaj Jain273b3e02012-06-22 19:08:03 -0700122#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
123#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 -0700124#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
125
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800126#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jia Meng3a3c6492013-12-19 17:16:52 +0800127#define DEFAULT_CONCEAL_COLOR "32896" //0x8080, black by default
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700128
129int debug_level = PRIO_ERROR;
130
Praveen Chavancf924182013-12-06 23:16:23 -0800131static const OMX_U32 kMaxSmoothStreamingWidth = 1920;
132static const OMX_U32 kMaxSmoothStreamingHeight = 1088;
133
Shalaj Jain273b3e02012-06-22 19:08:03 -0700134void* async_message_thread (void *input)
135{
Arun Menon906de572013-06-18 17:01:40 -0700136 OMX_BUFFERHEADERTYPE *buffer;
137 struct v4l2_plane plane[VIDEO_MAX_PLANES];
138 struct pollfd pfd;
139 struct v4l2_buffer v4l2_buf;
140 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
141 struct v4l2_event dqevent;
142 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
143 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
144 pfd.fd = omx->drv_ctx.video_driver_fd;
145 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700146 DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
Arun Menon906de572013-06-18 17:01:40 -0700147 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
148 while (1) {
149 rc = poll(&pfd, 1, POLL_TIMEOUT);
150 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700151 DEBUG_PRINT_ERROR("Poll timedout");
Arun Menon906de572013-06-18 17:01:40 -0700152 break;
153 } else if (rc < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700154 DEBUG_PRINT_ERROR("Error while polling: %d", rc);
Arun Menon906de572013-06-18 17:01:40 -0700155 break;
156 }
157 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
158 struct vdec_msginfo vdec_msg;
159 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
160 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
161 v4l2_buf.length = omx->drv_ctx.num_planes;
162 v4l2_buf.m.planes = plane;
163 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
164 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
165 vdec_msg.status_code=VDEC_S_SUCCESS;
166 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
167 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
168 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
169 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
170 (uint64_t)v4l2_buf.timestamp.tv_usec;
171 if (vdec_msg.msgdata.output_frame.len) {
172 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
173 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
174 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
175 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
176 }
177 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700178 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700179 break;
180 }
181 }
182 }
183 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
184 struct vdec_msginfo vdec_msg;
185 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
186 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
187 v4l2_buf.length = 1;
188 v4l2_buf.m.planes = plane;
189 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
190 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
191 vdec_msg.status_code=VDEC_S_SUCCESS;
192 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
193 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700194 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700195 break;
196 }
197 }
198 }
199 if (pfd.revents & POLLPRI) {
200 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
201 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
202 struct vdec_msginfo vdec_msg;
203 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
204 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700205 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved insufficient");
Arun Menon906de572013-06-18 17:01:40 -0700206 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700207 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700208 break;
209 }
210 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
211 struct vdec_msginfo vdec_msg;
212 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
213 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700214 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700215 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700216 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700217 break;
218 }
219 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
220 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700221 DEBUG_PRINT_HIGH("VIDC Output 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 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700227 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700228 break;
229 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
230 struct vdec_msginfo vdec_msg;
231 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
232 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700233 DEBUG_PRINT_HIGH("SYS Error Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700234 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700235 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700236 break;
237 }
Arun Menon45346052013-11-13 12:40:08 -0800238 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
Arun Menonbdb80b02013-08-12 17:45:54 -0700239 unsigned int *ptr = (unsigned int *)dqevent.u.data;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700240 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700241 omx->buf_ref_remove(ptr[0], ptr[1]);
242 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
243 unsigned int *ptr = (unsigned int *)dqevent.u.data;
244 struct vdec_msginfo vdec_msg;
245
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700246 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700247
248 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
249 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
250 v4l2_buf.length = omx->drv_ctx.num_planes;
251 v4l2_buf.m.planes = plane;
252 v4l2_buf.index = ptr[5];
253 v4l2_buf.flags = 0;
254
255 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
256 vdec_msg.status_code = VDEC_S_SUCCESS;
257 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
258 vdec_msg.msgdata.output_frame.len = 0;
259 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
260 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
261 (uint64_t)ptr[4];
262 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700263 DEBUG_PRINT_HIGH("async_message_thread Exitedn");
Arun Menonbdb80b02013-08-12 17:45:54 -0700264 break;
265 }
266 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700267 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700268 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
Arun Menon906de572013-06-18 17:01:40 -0700269 continue;
270 }
271 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700272 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700273 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700274 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700275}
276
277void* message_thread(void *input)
278{
Arun Menon906de572013-06-18 17:01:40 -0700279 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
280 unsigned char id;
281 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700282
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700283 DEBUG_PRINT_HIGH("omx_vdec: message thread start");
Arun Menon906de572013-06-18 17:01:40 -0700284 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
285 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700286
Arun Menon906de572013-06-18 17:01:40 -0700287 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700288
Arun Menon906de572013-06-18 17:01:40 -0700289 if (0 == n) {
290 break;
291 }
292
293 if (1 == n) {
294 omx->process_event_cb(omx, id);
295 }
296 if ((n < 0) && (errno != EINTR)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700297 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
Arun Menon906de572013-06-18 17:01:40 -0700298 break;
299 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700300 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700301 DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700302 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700303}
304
305void post_message(omx_vdec *omx, unsigned char id)
306{
Arun Menon906de572013-06-18 17:01:40 -0700307 int ret_value;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700308 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
Arun Menon906de572013-06-18 17:01:40 -0700309 ret_value = write(omx->m_pipe_out, &id, 1);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700310 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700311}
312
313// omx_cmd_queue destructor
314omx_vdec::omx_cmd_queue::~omx_cmd_queue()
315{
Arun Menon906de572013-06-18 17:01:40 -0700316 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700317}
318
319// omx cmd queue constructor
320omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
321{
322 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
323}
324
325// omx cmd queue insert
326bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
327{
Arun Menon906de572013-06-18 17:01:40 -0700328 bool ret = true;
329 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
330 m_q[m_write].id = id;
331 m_q[m_write].param1 = p1;
332 m_q[m_write].param2 = p2;
333 m_write++;
334 m_size ++;
335 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
336 m_write = 0;
337 }
338 } else {
339 ret = false;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700340 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700341 }
Arun Menon906de572013-06-18 17:01:40 -0700342 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700343}
344
345// omx cmd queue pop
346bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
347{
Arun Menon906de572013-06-18 17:01:40 -0700348 bool ret = true;
349 if (m_size > 0) {
350 *id = m_q[m_read].id;
351 *p1 = m_q[m_read].param1;
352 *p2 = m_q[m_read].param2;
353 // Move the read pointer ahead
354 ++m_read;
355 --m_size;
356 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
357 m_read = 0;
358 }
359 } else {
360 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700361 }
Arun Menon906de572013-06-18 17:01:40 -0700362 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700363}
364
365// Retrieve the first mesg type in the queue
366unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
367{
368 return m_q[m_read].id;
369}
370
371#ifdef _ANDROID_
372omx_vdec::ts_arr_list::ts_arr_list()
373{
Arun Menon906de572013-06-18 17:01:40 -0700374 //initialize timestamps array
375 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700376}
377omx_vdec::ts_arr_list::~ts_arr_list()
378{
Arun Menon906de572013-06-18 17:01:40 -0700379 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700380}
381
382bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
383{
Arun Menon906de572013-06-18 17:01:40 -0700384 bool ret = true;
385 bool duplicate_ts = false;
386 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700387
Arun Menon906de572013-06-18 17:01:40 -0700388 //insert at the first available empty location
389 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
390 if (!m_ts_arr_list[idx].valid) {
391 //found invalid or empty entry, save timestamp
392 m_ts_arr_list[idx].valid = true;
393 m_ts_arr_list[idx].timestamp = ts;
394 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
395 ts, idx);
396 break;
397 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700398 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700399
Arun Menon906de572013-06-18 17:01:40 -0700400 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
401 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
402 ret = false;
403 }
404 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700405}
406
407bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
408{
Arun Menon906de572013-06-18 17:01:40 -0700409 bool ret = true;
410 int min_idx = -1;
411 OMX_TICKS min_ts = 0;
412 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700413
Arun Menon906de572013-06-18 17:01:40 -0700414 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700415
Arun Menon906de572013-06-18 17:01:40 -0700416 if (m_ts_arr_list[idx].valid) {
417 //found valid entry, save index
418 if (min_idx < 0) {
419 //first valid entry
420 min_ts = m_ts_arr_list[idx].timestamp;
421 min_idx = idx;
422 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
423 min_ts = m_ts_arr_list[idx].timestamp;
424 min_idx = idx;
425 }
426 }
427
Shalaj Jain273b3e02012-06-22 19:08:03 -0700428 }
429
Arun Menon906de572013-06-18 17:01:40 -0700430 if (min_idx < 0) {
431 //no valid entries found
432 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
433 ts = 0;
434 ret = false;
435 } else {
436 ts = m_ts_arr_list[min_idx].timestamp;
437 m_ts_arr_list[min_idx].valid = false;
438 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
439 ts, min_idx);
440 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700441
Arun Menon906de572013-06-18 17:01:40 -0700442 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700443
444}
445
446
447bool omx_vdec::ts_arr_list::reset_ts_list()
448{
Arun Menon906de572013-06-18 17:01:40 -0700449 bool ret = true;
450 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700451
Arun Menon906de572013-06-18 17:01:40 -0700452 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
453 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
454 m_ts_arr_list[idx].valid = false;
455 }
456 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700457}
458#endif
459
460// factory function executed by the core to create instances
461void *get_omx_component_factory_fn(void)
462{
Arun Menon906de572013-06-18 17:01:40 -0700463 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700464}
465
466#ifdef _ANDROID_
467#ifdef USE_ION
468VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700469 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700470{
Arun Menon906de572013-06-18 17:01:40 -0700471 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700472}
473#else
474VideoHeap::VideoHeap(int fd, size_t size, void* base)
475{
476 // dup file descriptor, map once, use pmem
477 init(dup(fd), base, size, 0 , MEM_DEVICE);
478}
479#endif
480#endif // _ANDROID_
481/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700482 FUNCTION
483 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700484
Arun Menon906de572013-06-18 17:01:40 -0700485 DESCRIPTION
486 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700487
Arun Menon906de572013-06-18 17:01:40 -0700488 PARAMETERS
489 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700490
Arun Menon906de572013-06-18 17:01:40 -0700491 RETURN VALUE
492 None.
493 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800494omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700495 m_state(OMX_StateInvalid),
496 m_app_data(NULL),
497 m_inp_mem_ptr(NULL),
498 m_out_mem_ptr(NULL),
499 m_inp_err_count(0),
500 input_flush_progress (false),
501 output_flush_progress (false),
502 input_use_buffer (false),
503 output_use_buffer (false),
504 ouput_egl_buffers(false),
505 m_use_output_pmem(OMX_FALSE),
506 m_out_mem_region_smi(OMX_FALSE),
507 m_out_pvt_entry_pmem(OMX_FALSE),
508 pending_input_buffers(0),
509 pending_output_buffers(0),
510 m_out_bm_count(0),
511 m_inp_bm_count(0),
512 m_inp_bPopulated(OMX_FALSE),
513 m_out_bPopulated(OMX_FALSE),
514 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700515#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700516 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700517#endif
Arun Menon906de572013-06-18 17:01:40 -0700518 m_inp_bEnabled(OMX_TRUE),
519 m_out_bEnabled(OMX_TRUE),
520 m_in_alloc_cnt(0),
521 m_platform_list(NULL),
522 m_platform_entry(NULL),
523 m_pmem_info(NULL),
524 arbitrary_bytes (true),
525 psource_frame (NULL),
526 pdest_frame (NULL),
527 m_inp_heap_ptr (NULL),
528 m_phdr_pmem_ptr(NULL),
529 m_heap_inp_bm_count (0),
530 codec_type_parse ((codec_type)0),
531 first_frame_meta (true),
532 frame_count (0),
533 nal_count (0),
534 nal_length(0),
535 look_ahead_nal (false),
536 first_frame(0),
537 first_buffer(NULL),
538 first_frame_size (0),
539 m_device_file_ptr(NULL),
540 m_vc1_profile((vc1_profile_type)0),
Arun Menon906de572013-06-18 17:01:40 -0700541 h264_last_au_ts(LLONG_MAX),
542 h264_last_au_flags(0),
Surajit Podderd2644d52013-08-28 17:59:06 +0530543 m_disp_hor_size(0),
544 m_disp_vert_size(0),
Arun Menon906de572013-06-18 17:01:40 -0700545 prev_ts(LLONG_MAX),
546 rst_prev_ts(true),
547 frm_int(0),
Arun Menon906de572013-06-18 17:01:40 -0700548 in_reconfig(false),
549 m_display_id(NULL),
550 h264_parser(NULL),
551 client_extradata(0),
552 m_reject_avc_1080p_mp (0),
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +0530553 m_other_extradata(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700554#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700555 m_enable_android_native_buffers(OMX_FALSE),
556 m_use_android_native_buffers(OMX_FALSE),
557 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700558#endif
Arun Menon906de572013-06-18 17:01:40 -0700559 m_desc_buffer_ptr(NULL),
560 secure_mode(false),
Surajit Podderd2644d52013-08-28 17:59:06 +0530561 m_profile(0),
Arun Menon906de572013-06-18 17:01:40 -0700562 client_set_fps(false)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700563{
Arun Menon906de572013-06-18 17:01:40 -0700564 /* Assumption is that , to begin with , we have all the frames with decoder */
565 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700566 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700567#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700568 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700569 property_get("vidc.debug.level", property_value, "0");
570 debug_level = atoi(property_value);
571 property_value[0] = '\0';
572
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700573 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
574
Arun Menon906de572013-06-18 17:01:40 -0700575 property_get("vidc.dec.debug.perf", property_value, "0");
576 perf_flag = atoi(property_value);
577 if (perf_flag) {
578 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
579 dec_time.start();
580 proc_frms = latency = 0;
581 }
582 prev_n_filled_len = 0;
583 property_value[0] = '\0';
584 property_get("vidc.dec.debug.ts", property_value, "0");
585 m_debug_timestamp = atoi(property_value);
586 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
587 if (m_debug_timestamp) {
588 time_stamp_dts.set_timestamp_reorder_mode(true);
589 time_stamp_dts.enable_debug_print(true);
590 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700591
Arun Menon906de572013-06-18 17:01:40 -0700592 property_value[0] = '\0';
593 property_get("vidc.dec.debug.concealedmb", property_value, "0");
594 m_debug_concealedmb = atoi(property_value);
595 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700596
Arun Menon906de572013-06-18 17:01:40 -0700597 property_value[0] = '\0';
598 property_get("vidc.dec.profile.check", property_value, "0");
599 m_reject_avc_1080p_mp = atoi(property_value);
600 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530601
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700602 property_value[0] = '\0';
603 property_get("vidc.dec.log.in", property_value, "0");
604 m_debug.in_buffer_log = atoi(property_value);
605
606 property_value[0] = '\0';
607 property_get("vidc.dec.log.out", property_value, "0");
608 m_debug.out_buffer_log = atoi(property_value);
609 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
610
611 property_value[0] = '\0';
612 property_get("vidc.log.loc", property_value, "");
613 if (*property_value)
614 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700615#endif
Arun Menon906de572013-06-18 17:01:40 -0700616 memset(&m_cmp,0,sizeof(m_cmp));
617 memset(&m_cb,0,sizeof(m_cb));
618 memset (&drv_ctx,0,sizeof(drv_ctx));
619 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
620 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
621 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
622 m_demux_entries = 0;
623 msg_thread_id = 0;
624 async_thread_id = 0;
625 msg_thread_created = false;
626 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700627#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700628 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700629#endif
Arun Menon906de572013-06-18 17:01:40 -0700630 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Maheshwar Ajjad2df2182013-10-24 19:20:34 +0530631 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -0700632 drv_ctx.timestamp_adjust = false;
633 drv_ctx.video_driver_fd = -1;
634 m_vendor_config.pData = NULL;
635 pthread_mutex_init(&m_lock, NULL);
636 pthread_mutex_init(&c_lock, NULL);
637 sem_init(&m_cmd_lock,0,0);
638 streaming[CAPTURE_PORT] =
639 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700640#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700641 char extradata_value[PROPERTY_VALUE_MAX] = {0};
642 property_get("vidc.dec.debug.extradata", extradata_value, "0");
643 m_debug_extradata = atoi(extradata_value);
644 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700645#endif
Arun Menon906de572013-06-18 17:01:40 -0700646 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
647 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700648 dynamic_buf_mode = false;
649 out_dynamic_list = NULL;
Praveen Chavane78460c2013-12-06 23:16:04 -0800650 is_down_scalar_enabled = false;
Praveen Chavancf924182013-12-06 23:16:23 -0800651 m_smoothstreaming_mode = false;
652 m_smoothstreaming_width = 0;
653 m_smoothstreaming_height = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700654}
655
Vinay Kalia85793762012-06-14 19:12:34 -0700656static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700657 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
658 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
659 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700660 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
661 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
Arun Menon906de572013-06-18 17:01:40 -0700662 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
663 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700664};
665
666static OMX_ERRORTYPE subscribe_to_events(int fd)
667{
Arun Menon906de572013-06-18 17:01:40 -0700668 OMX_ERRORTYPE eRet = OMX_ErrorNone;
669 struct v4l2_event_subscription sub;
670 int array_sz = sizeof(event_type)/sizeof(int);
671 int i,rc;
672 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700673 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700674 return OMX_ErrorBadParameter;
675 }
Vinay Kalia85793762012-06-14 19:12:34 -0700676
Arun Menon906de572013-06-18 17:01:40 -0700677 for (i = 0; i < array_sz; ++i) {
678 memset(&sub, 0, sizeof(sub));
679 sub.type = event_type[i];
680 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
681 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700682 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700683 break;
684 }
685 }
686 if (i < array_sz) {
687 for (--i; i >=0 ; i--) {
688 memset(&sub, 0, sizeof(sub));
689 sub.type = event_type[i];
690 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
691 if (rc)
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700692 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700693 }
694 eRet = OMX_ErrorNotImplemented;
695 }
696 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700697}
698
699
700static OMX_ERRORTYPE unsubscribe_to_events(int fd)
701{
Arun Menon906de572013-06-18 17:01:40 -0700702 OMX_ERRORTYPE eRet = OMX_ErrorNone;
703 struct v4l2_event_subscription sub;
704 int array_sz = sizeof(event_type)/sizeof(int);
705 int i,rc;
706 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700707 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700708 return OMX_ErrorBadParameter;
709 }
Vinay Kalia85793762012-06-14 19:12:34 -0700710
Arun Menon906de572013-06-18 17:01:40 -0700711 for (i = 0; i < array_sz; ++i) {
712 memset(&sub, 0, sizeof(sub));
713 sub.type = event_type[i];
714 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
715 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700716 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700717 break;
718 }
719 }
720 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700721}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700722
723/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700724 FUNCTION
725 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700726
Arun Menon906de572013-06-18 17:01:40 -0700727 DESCRIPTION
728 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700729
Arun Menon906de572013-06-18 17:01:40 -0700730 PARAMETERS
731 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700732
Arun Menon906de572013-06-18 17:01:40 -0700733 RETURN VALUE
734 None.
735 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700736omx_vdec::~omx_vdec()
737{
Arun Menon906de572013-06-18 17:01:40 -0700738 m_pmem_info = NULL;
739 struct v4l2_decoder_cmd dec;
740 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
741 if (m_pipe_in) close(m_pipe_in);
742 if (m_pipe_out) close(m_pipe_out);
743 m_pipe_in = -1;
744 m_pipe_out = -1;
745 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
746 if (msg_thread_created)
747 pthread_join(msg_thread_id,NULL);
748 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
749 dec.cmd = V4L2_DEC_CMD_STOP;
750 if (drv_ctx.video_driver_fd >=0 ) {
751 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700752 DEBUG_PRINT_ERROR("STOP Command failed");
Arun Menon906de572013-06-18 17:01:40 -0700753 }
754 if (async_thread_created)
755 pthread_join(async_thread_id,NULL);
756 unsubscribe_to_events(drv_ctx.video_driver_fd);
757 close(drv_ctx.video_driver_fd);
758 pthread_mutex_destroy(&m_lock);
759 pthread_mutex_destroy(&c_lock);
760 sem_destroy(&m_cmd_lock);
761 if (perf_flag) {
762 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
763 dec_time.end();
764 }
765 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700766}
767
Arun Menon906de572013-06-18 17:01:40 -0700768int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
769{
770 struct v4l2_requestbuffers bufreq;
771 int rc = 0;
772 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
773 bufreq.memory = V4L2_MEMORY_USERPTR;
774 bufreq.count = 0;
775 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
776 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530777 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
778 bufreq.memory = V4L2_MEMORY_USERPTR;
779 bufreq.count = 0;
780 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
781 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700782 }
783 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700784}
785
Shalaj Jain273b3e02012-06-22 19:08:03 -0700786/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700787 FUNCTION
788 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700789
Arun Menon906de572013-06-18 17:01:40 -0700790 DESCRIPTION
791 IL Client callbacks are generated through this routine. The decoder
792 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700793
Arun Menon906de572013-06-18 17:01:40 -0700794 PARAMETERS
795 ctxt -- Context information related to the self.
796 id -- Event identifier. This could be any of the following:
797 1. Command completion event
798 2. Buffer done callback event
799 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700800
Arun Menon906de572013-06-18 17:01:40 -0700801 RETURN VALUE
802 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700803
Arun Menon906de572013-06-18 17:01:40 -0700804 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700805void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
806{
Arun Menon906de572013-06-18 17:01:40 -0700807 signed p1; // Parameter - 1
808 signed p2; // Parameter - 2
809 unsigned ident;
810 unsigned qsize=0; // qsize
811 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700812
Arun Menon906de572013-06-18 17:01:40 -0700813 if (!pThis) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700814 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
Arun Menon906de572013-06-18 17:01:40 -0700815 __func__);
816 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700817 }
818
Arun Menon906de572013-06-18 17:01:40 -0700819 // Protect the shared queue data structure
820 do {
821 /*Read the message id's from the queue*/
822 pthread_mutex_lock(&pThis->m_lock);
823 qsize = pThis->m_cmd_q.m_size;
824 if (qsize) {
825 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700826 }
Arun Menon906de572013-06-18 17:01:40 -0700827
828 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
829 qsize = pThis->m_ftb_q.m_size;
830 if (qsize) {
831 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
832 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700833 }
Arun Menon906de572013-06-18 17:01:40 -0700834
835 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
836 qsize = pThis->m_etb_q.m_size;
837 if (qsize) {
838 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
839 }
840 }
841 pthread_mutex_unlock(&pThis->m_lock);
842
843 /*process message if we have one*/
844 if (qsize > 0) {
845 id = ident;
846 switch (id) {
847 case OMX_COMPONENT_GENERATE_EVENT:
848 if (pThis->m_cb.EventHandler) {
849 switch (p1) {
850 case OMX_CommandStateSet:
851 pThis->m_state = (OMX_STATETYPE) p2;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700852 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
Arun Menon906de572013-06-18 17:01:40 -0700853 pThis->m_state);
854 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
855 OMX_EventCmdComplete, p1, p2, NULL);
856 break;
857
858 case OMX_EventError:
859 if (p2 == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700860 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
Arun Menon906de572013-06-18 17:01:40 -0700861 pThis->m_state = (OMX_STATETYPE) p2;
862 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
863 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
864 } else if (p2 == OMX_ErrorHardware) {
865 pThis->omx_report_error();
866 } else {
867 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
868 OMX_EventError, p2, (OMX_U32)NULL, NULL );
869 }
870 break;
871
872 case OMX_CommandPortDisable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700873 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700874 if (BITMASK_PRESENT(&pThis->m_flags,
875 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
876 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
877 break;
878 }
879 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
880 OMX_ERRORTYPE eRet = OMX_ErrorNone;
881 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
882 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700883 DEBUG_PRINT_HIGH("Failed to release output buffers");
Arun Menon906de572013-06-18 17:01:40 -0700884 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
885 pThis->in_reconfig = false;
886 if (eRet != OMX_ErrorNone) {
887 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
888 pThis->omx_report_error();
889 break;
890 }
891 }
892 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
893 OMX_EventCmdComplete, p1, p2, NULL );
894 break;
895 case OMX_CommandPortEnable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700896 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700897 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
898 OMX_EventCmdComplete, p1, p2, NULL );
899 break;
900
901 default:
902 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
903 OMX_EventCmdComplete, p1, p2, NULL );
904 break;
905
906 }
907 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700908 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Arun Menon906de572013-06-18 17:01:40 -0700909 }
910 break;
911 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
912 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
913 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700914 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
Arun Menon906de572013-06-18 17:01:40 -0700915 pThis->omx_report_error ();
916 }
917 break;
918 case OMX_COMPONENT_GENERATE_ETB:
919 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
920 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700921 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700922 pThis->omx_report_error ();
923 }
924 break;
925
926 case OMX_COMPONENT_GENERATE_FTB:
927 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
928 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700929 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700930 pThis->omx_report_error ();
931 }
932 break;
933
934 case OMX_COMPONENT_GENERATE_COMMAND:
935 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
936 (OMX_U32)p2,(OMX_PTR)NULL);
937 break;
938
939 case OMX_COMPONENT_GENERATE_EBD:
940
941 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700942 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700943 pThis->omx_report_error ();
944 } else {
945 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
946 pThis->m_inp_err_count++;
947 pThis->time_stamp_dts.remove_time_stamp(
948 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
949 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
950 ?true:false);
951 } else {
952 pThis->m_inp_err_count = 0;
953 }
954 if ( pThis->empty_buffer_done(&pThis->m_cmp,
955 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700956 DEBUG_PRINT_ERROR("empty_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700957 pThis->omx_report_error ();
958 }
959 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700960 DEBUG_PRINT_ERROR("Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
Arun Menon906de572013-06-18 17:01:40 -0700961 pThis->omx_report_error ();
962 }
963 }
964 break;
965 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
966 int64_t *timestamp = (int64_t *)p1;
967 if (p1) {
968 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
969 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
970 ?true:false);
971 free(timestamp);
972 }
973 }
974 break;
975 case OMX_COMPONENT_GENERATE_FBD:
976 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700977 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700978 pThis->omx_report_error ();
979 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
980 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700981 DEBUG_PRINT_ERROR("fill_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700982 pThis->omx_report_error ();
983 }
984 break;
985
986 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700987 DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -0700988 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700989 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -0700990 } else {
991 pThis->execute_input_flush();
992 if (pThis->m_cb.EventHandler) {
993 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700994 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
Arun Menon906de572013-06-18 17:01:40 -0700995 pThis->omx_report_error ();
996 } else {
997 /*Check if we need generate event for Flush done*/
998 if (BITMASK_PRESENT(&pThis->m_flags,
999 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
1000 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001001 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
Arun Menon906de572013-06-18 17:01:40 -07001002 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1003 OMX_EventCmdComplete,OMX_CommandFlush,
1004 OMX_CORE_INPUT_PORT_INDEX,NULL );
1005 }
1006 if (BITMASK_PRESENT(&pThis->m_flags,
1007 OMX_COMPONENT_IDLE_PENDING)) {
1008 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001009 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
Arun Menon906de572013-06-18 17:01:40 -07001010 pThis->omx_report_error ();
1011 } else {
1012 pThis->streaming[OUTPUT_PORT] = false;
1013 }
1014 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001015 DEBUG_PRINT_LOW("Input flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001016 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1017 OMX_COMPONENT_GENERATE_STOP_DONE);
1018 }
1019 }
1020 }
1021 } else {
1022 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1023 }
1024 }
1025 break;
1026
1027 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001028 DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001029 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001030 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001031 } else {
1032 pThis->execute_output_flush();
1033 if (pThis->m_cb.EventHandler) {
1034 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001035 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
Arun Menon906de572013-06-18 17:01:40 -07001036 pThis->omx_report_error ();
1037 } else {
1038 /*Check if we need generate event for Flush done*/
1039 if (BITMASK_PRESENT(&pThis->m_flags,
1040 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001041 DEBUG_PRINT_LOW("Notify Output Flush done");
Arun Menon906de572013-06-18 17:01:40 -07001042 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1043 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1044 OMX_EventCmdComplete,OMX_CommandFlush,
1045 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1046 }
1047 if (BITMASK_PRESENT(&pThis->m_flags,
1048 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001049 DEBUG_PRINT_LOW("Internal flush complete");
Arun Menon906de572013-06-18 17:01:40 -07001050 BITMASK_CLEAR (&pThis->m_flags,
1051 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1052 if (BITMASK_PRESENT(&pThis->m_flags,
1053 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1054 pThis->post_event(OMX_CommandPortDisable,
1055 OMX_CORE_OUTPUT_PORT_INDEX,
1056 OMX_COMPONENT_GENERATE_EVENT);
1057 BITMASK_CLEAR (&pThis->m_flags,
1058 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1059
1060 }
1061 }
1062
1063 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1064 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001065 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
Arun Menon906de572013-06-18 17:01:40 -07001066 pThis->omx_report_error ();
1067 break;
1068 }
1069 pThis->streaming[CAPTURE_PORT] = false;
1070 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001071 DEBUG_PRINT_LOW("Output flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001072 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1073 OMX_COMPONENT_GENERATE_STOP_DONE);
1074 }
1075 }
1076 }
1077 } else {
1078 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1079 }
1080 }
1081 break;
1082
1083 case OMX_COMPONENT_GENERATE_START_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001084 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001085
1086 if (pThis->m_cb.EventHandler) {
1087 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001088 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
Arun Menon906de572013-06-18 17:01:40 -07001089 pThis->omx_report_error ();
1090 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001091 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001092 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001093 DEBUG_PRINT_LOW("Move to executing");
Arun Menon906de572013-06-18 17:01:40 -07001094 // Send the callback now
1095 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1096 pThis->m_state = OMX_StateExecuting;
1097 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1098 OMX_EventCmdComplete,OMX_CommandStateSet,
1099 OMX_StateExecuting, NULL);
1100 } else if (BITMASK_PRESENT(&pThis->m_flags,
1101 OMX_COMPONENT_PAUSE_PENDING)) {
1102 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1103 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001104 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
Arun Menon906de572013-06-18 17:01:40 -07001105 pThis->omx_report_error ();
1106 }
1107 }
1108 }
1109 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001110 DEBUG_PRINT_LOW("Event Handler callback is NULL");
Arun Menon906de572013-06-18 17:01:40 -07001111 }
1112 break;
1113
1114 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001115 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001116 if (pThis->m_cb.EventHandler) {
1117 if (p2 != VDEC_S_SUCCESS) {
1118 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1119 pThis->omx_report_error ();
1120 } else {
1121 pThis->complete_pending_buffer_done_cbs();
1122 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001123 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
Arun Menon906de572013-06-18 17:01:40 -07001124 //Send the callback now
1125 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1126 pThis->m_state = OMX_StatePause;
1127 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1128 OMX_EventCmdComplete,OMX_CommandStateSet,
1129 OMX_StatePause, NULL);
1130 }
1131 }
1132 } else {
1133 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1134 }
1135
1136 break;
1137
1138 case OMX_COMPONENT_GENERATE_RESUME_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001139 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001140 if (pThis->m_cb.EventHandler) {
1141 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001142 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
Arun Menon906de572013-06-18 17:01:40 -07001143 pThis->omx_report_error ();
1144 } else {
1145 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001146 DEBUG_PRINT_LOW("Moving the decoder to execute state");
Arun Menon906de572013-06-18 17:01:40 -07001147 // Send the callback now
1148 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1149 pThis->m_state = OMX_StateExecuting;
1150 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1151 OMX_EventCmdComplete,OMX_CommandStateSet,
1152 OMX_StateExecuting,NULL);
1153 }
1154 }
1155 } else {
1156 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1157 }
1158
1159 break;
1160
1161 case OMX_COMPONENT_GENERATE_STOP_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001162 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001163 if (pThis->m_cb.EventHandler) {
1164 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001165 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
Arun Menon906de572013-06-18 17:01:40 -07001166 pThis->omx_report_error ();
1167 } else {
1168 pThis->complete_pending_buffer_done_cbs();
1169 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001170 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001171 // Send the callback now
1172 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1173 pThis->m_state = OMX_StateIdle;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001174 DEBUG_PRINT_LOW("Move to Idle State");
Arun Menon906de572013-06-18 17:01:40 -07001175 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1176 OMX_EventCmdComplete,OMX_CommandStateSet,
1177 OMX_StateIdle,NULL);
1178 }
1179 }
1180 } else {
1181 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1182 }
1183
1184 break;
1185
1186 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001187 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Arun Menon906de572013-06-18 17:01:40 -07001188
1189 if (p2 == OMX_IndexParamPortDefinition) {
1190 pThis->in_reconfig = true;
1191 }
1192 if (pThis->m_cb.EventHandler) {
1193 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1194 OMX_EventPortSettingsChanged, p1, p2, NULL );
1195 } else {
1196 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1197 }
1198
Arun Menon906de572013-06-18 17:01:40 -07001199 break;
1200
1201 case OMX_COMPONENT_GENERATE_EOS_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001202 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001203 if (pThis->m_cb.EventHandler) {
1204 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1205 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1206 } else {
1207 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1208 }
1209 pThis->prev_ts = LLONG_MAX;
1210 pThis->rst_prev_ts = true;
1211 break;
1212
1213 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001214 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
Arun Menon906de572013-06-18 17:01:40 -07001215 pThis->omx_report_error ();
1216 break;
1217
1218 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001219 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
Arun Menon906de572013-06-18 17:01:40 -07001220 pThis->omx_report_unsupported_setting();
1221 break;
1222
Arun Menon906de572013-06-18 17:01:40 -07001223 default:
1224 break;
1225 }
1226 }
1227 pthread_mutex_lock(&pThis->m_lock);
1228 qsize = pThis->m_cmd_q.m_size;
1229 if (pThis->m_state != OMX_StatePause)
1230 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1231 pthread_mutex_unlock(&pThis->m_lock);
1232 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001233
1234}
1235
Vinay Kaliab9e98102013-04-02 19:31:43 -07001236int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001237{
Arun Menon906de572013-06-18 17:01:40 -07001238 int format_changed = 0;
Surajit Podderd2644d52013-08-28 17:59:06 +05301239 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1240 (width != (int)drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001241 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
Arun Menon906de572013-06-18 17:01:40 -07001242 width, drv_ctx.video_resolution.frame_width,
1243 height,drv_ctx.video_resolution.frame_height);
1244 format_changed = 1;
1245 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001246 drv_ctx.video_resolution.frame_height = height;
1247 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001248 drv_ctx.video_resolution.scan_lines = scan_lines;
1249 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001250 rectangle.nLeft = 0;
1251 rectangle.nTop = 0;
1252 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1253 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Arun Menon906de572013-06-18 17:01:40 -07001254 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001255}
1256
Arun Menon6836ba02013-02-19 20:37:40 -08001257OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1258{
Arun Menon906de572013-06-18 17:01:40 -07001259 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1260 OMX_MAX_STRINGNAME_SIZE) &&
1261 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1262 m_decoder_capability.max_width = 1280;
1263 m_decoder_capability.max_height = 720;
1264 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1265 }
Arun Menon888aa852013-05-30 11:24:42 -07001266
Arun Menon906de572013-06-18 17:01:40 -07001267 if ((drv_ctx.video_resolution.frame_width *
1268 drv_ctx.video_resolution.frame_height >
1269 m_decoder_capability.max_width *
1270 m_decoder_capability.max_height) ||
1271 (drv_ctx.video_resolution.frame_width*
1272 drv_ctx.video_resolution.frame_height <
1273 m_decoder_capability.min_width *
1274 m_decoder_capability.min_height)) {
1275 DEBUG_PRINT_ERROR(
1276 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1277 drv_ctx.video_resolution.frame_width,
1278 drv_ctx.video_resolution.frame_height,
1279 m_decoder_capability.min_width,
1280 m_decoder_capability.min_height,
1281 m_decoder_capability.max_width,
1282 m_decoder_capability.max_height);
1283 return OMX_ErrorUnsupportedSetting;
1284 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001285 DEBUG_PRINT_HIGH("video session supported");
Arun Menon906de572013-06-18 17:01:40 -07001286 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001287}
1288
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001289int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1290{
1291 if (m_debug.in_buffer_log && !m_debug.infile) {
1292 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1293 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1294 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1295 }
1296 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1297 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); }
1298 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1299 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
1300 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1301 }
1302 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
1303 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1304 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1305 }
1306 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1307 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1308 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1309 }
1310 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1311 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1312 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1313 }
1314 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1315 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1316 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1317 }
1318 m_debug.infile = fopen (m_debug.infile_name, "ab");
1319 if (!m_debug.infile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001320 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001321 m_debug.infile_name[0] = '\0';
1322 return -1;
1323 }
1324 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1325 struct ivf_file_header {
1326 OMX_U8 signature[4]; //='DKIF';
1327 OMX_U8 version ; //= 0;
1328 OMX_U8 headersize ; //= 32;
1329 OMX_U32 FourCC;
1330 OMX_U8 width;
1331 OMX_U8 height;
1332 OMX_U32 rate;
1333 OMX_U32 scale;
1334 OMX_U32 length;
1335 OMX_U8 unused[4];
1336 } file_header;
1337
1338 memset((void *)&file_header,0,sizeof(file_header));
1339 file_header.signature[0] = 'D';
1340 file_header.signature[1] = 'K';
1341 file_header.signature[2] = 'I';
1342 file_header.signature[3] = 'F';
1343 file_header.version = 0;
1344 file_header.headersize = 32;
1345 file_header.FourCC = 0x30385056;
1346 fwrite((const char *)&file_header,
1347 sizeof(file_header),1,m_debug.infile);
1348 }
1349 }
1350 if (m_debug.infile && buffer_addr && buffer_len) {
1351 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1352 struct vp8_ivf_frame_header {
1353 OMX_U32 framesize;
1354 OMX_U32 timestamp_lo;
1355 OMX_U32 timestamp_hi;
1356 } vp8_frame_header;
1357 vp8_frame_header.framesize = buffer_len;
1358 /* Currently FW doesn't use timestamp values */
1359 vp8_frame_header.timestamp_lo = 0;
1360 vp8_frame_header.timestamp_hi = 0;
1361 fwrite((const char *)&vp8_frame_header,
1362 sizeof(vp8_frame_header),1,m_debug.infile);
1363 }
1364 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1365 }
1366 return 0;
1367}
1368
1369int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1370 if (m_debug.out_buffer_log && !m_debug.outfile) {
1371 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1372 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1373 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1374 if (!m_debug.outfile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001375 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001376 m_debug.outfile_name[0] = '\0';
1377 return -1;
1378 }
1379 }
1380 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1381 int buf_index = buffer - m_out_mem_ptr;
1382 int stride = drv_ctx.video_resolution.stride;
1383 int scanlines = drv_ctx.video_resolution.scan_lines;
1384 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1385 unsigned i;
1386 int bytes_written = 0;
1387 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1388 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1389 temp += stride;
1390 }
1391 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1392 int stride_c = stride;
1393 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1394 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1395 temp += stride_c;
1396 }
1397 }
1398 return 0;
1399}
1400
Shalaj Jain273b3e02012-06-22 19:08:03 -07001401/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001402 FUNCTION
1403 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001404
Arun Menon906de572013-06-18 17:01:40 -07001405 DESCRIPTION
1406 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001407
Arun Menon906de572013-06-18 17:01:40 -07001408 PARAMETERS
1409 ctxt -- Context information related to the self.
1410 id -- Event identifier. This could be any of the following:
1411 1. Command completion event
1412 2. Buffer done callback event
1413 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001414
Arun Menon906de572013-06-18 17:01:40 -07001415 RETURN VALUE
1416 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001417
Arun Menon906de572013-06-18 17:01:40 -07001418 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001419OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1420{
1421
Arun Menon906de572013-06-18 17:01:40 -07001422 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1423 struct v4l2_fmtdesc fdesc;
1424 struct v4l2_format fmt;
1425 struct v4l2_requestbuffers bufreq;
1426 struct v4l2_control control;
1427 struct v4l2_frmsizeenum frmsize;
1428 unsigned int alignment = 0,buffer_size = 0;
1429 int fds[2];
1430 int r,ret=0;
1431 bool codec_ambiguous = false;
1432 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Jia Meng3a3c6492013-12-19 17:16:52 +08001433 char property_value[PROPERTY_VALUE_MAX] = {0};
Sachin Shahc82a18f2013-03-29 14:45:38 -07001434
1435#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001436 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001437 property_get("ro.board.platform", platform_name, "0");
1438 if (!strncmp(platform_name, "msm8610", 7)) {
1439 device_name = (OMX_STRING)"/dev/video/q6_dec";
1440 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001441#endif
1442
Arun Menon906de572013-06-18 17:01:40 -07001443 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1444 struct v4l2_control control;
1445 secure_mode = true;
1446 arbitrary_bytes = false;
1447 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301448 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
1449 OMX_MAX_STRINGNAME_SIZE)){
1450 secure_mode = true;
1451 arbitrary_bytes = false;
1452 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
Arun Menon906de572013-06-18 17:01:40 -07001453 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001454
Arun Menon906de572013-06-18 17:01:40 -07001455 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001456
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001457 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d",
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001458 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001459
Arun Menon906de572013-06-18 17:01:40 -07001460 if (drv_ctx.video_driver_fd == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001461 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
Arun Menon906de572013-06-18 17:01:40 -07001462 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1463 close(0);
1464 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001465
Arun Menon906de572013-06-18 17:01:40 -07001466 if (drv_ctx.video_driver_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001467 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
Arun Menon906de572013-06-18 17:01:40 -07001468 return OMX_ErrorInsufficientResources;
1469 }
1470 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1471 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001472
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001473 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001474 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001475 async_thread_created = true;
1476 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1477 }
1478 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001479 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
Arun Menon906de572013-06-18 17:01:40 -07001480 async_thread_created = false;
1481 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001482 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001483
Shalaj Jain273b3e02012-06-22 19:08:03 -07001484#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07001485 outputExtradataFile = fopen (ouputextradatafilename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001486#endif
1487
Arun Menon906de572013-06-18 17:01:40 -07001488 // Copy the role information which provides the decoder kind
1489 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001490
Arun Menon906de572013-06-18 17:01:40 -07001491 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1492 OMX_MAX_STRINGNAME_SIZE)) {
1493 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1494 OMX_MAX_STRINGNAME_SIZE);
1495 drv_ctx.timestamp_adjust = true;
1496 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1497 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1498 output_capability=V4L2_PIX_FMT_MPEG4;
1499 /*Initialize Start Code for MPEG4*/
1500 codec_type_parse = CODEC_TYPE_MPEG4;
1501 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001502 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1503 OMX_MAX_STRINGNAME_SIZE)) {
1504 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1505 OMX_MAX_STRINGNAME_SIZE);
1506 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1507 output_capability = V4L2_PIX_FMT_MPEG2;
1508 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1509 /*Initialize Start Code for MPEG2*/
1510 codec_type_parse = CODEC_TYPE_MPEG2;
1511 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001512 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1513 OMX_MAX_STRINGNAME_SIZE)) {
1514 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001515 DEBUG_PRINT_LOW("H263 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001516 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1517 eCompressionFormat = OMX_VIDEO_CodingH263;
1518 output_capability = V4L2_PIX_FMT_H263;
1519 codec_type_parse = CODEC_TYPE_H263;
1520 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001521 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1522 OMX_MAX_STRINGNAME_SIZE)) {
1523 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001524 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001525 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1526 output_capability = V4L2_PIX_FMT_DIVX_311;
1527 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1528 codec_type_parse = CODEC_TYPE_DIVX;
1529 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001530
Arun Menon906de572013-06-18 17:01:40 -07001531 eRet = createDivxDrmContext();
1532 if (eRet != OMX_ErrorNone) {
1533 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1534 return eRet;
1535 }
1536 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1537 OMX_MAX_STRINGNAME_SIZE)) {
1538 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001539 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001540 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1541 output_capability = V4L2_PIX_FMT_DIVX;
1542 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1543 codec_type_parse = CODEC_TYPE_DIVX;
1544 codec_ambiguous = true;
1545 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001546
Arun Menon906de572013-06-18 17:01:40 -07001547 eRet = createDivxDrmContext();
1548 if (eRet != OMX_ErrorNone) {
1549 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1550 return eRet;
1551 }
1552 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1553 OMX_MAX_STRINGNAME_SIZE)) {
1554 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001555 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001556 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1557 output_capability = V4L2_PIX_FMT_DIVX;
1558 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1559 codec_type_parse = CODEC_TYPE_DIVX;
1560 codec_ambiguous = true;
1561 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001562
Arun Menon906de572013-06-18 17:01:40 -07001563 eRet = createDivxDrmContext();
1564 if (eRet != OMX_ErrorNone) {
1565 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1566 return eRet;
1567 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001568
Arun Menon906de572013-06-18 17:01:40 -07001569 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1570 OMX_MAX_STRINGNAME_SIZE)) {
1571 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1572 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1573 output_capability=V4L2_PIX_FMT_H264;
1574 eCompressionFormat = OMX_VIDEO_CodingAVC;
1575 codec_type_parse = CODEC_TYPE_H264;
1576 m_frame_parser.init_start_codes (codec_type_parse);
1577 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001578 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1579 OMX_MAX_STRINGNAME_SIZE)) {
1580 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1581 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1582 eCompressionFormat = OMX_VIDEO_CodingWMV;
1583 codec_type_parse = CODEC_TYPE_VC1;
1584 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1585 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001586 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1587 OMX_MAX_STRINGNAME_SIZE)) {
1588 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1589 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1590 eCompressionFormat = OMX_VIDEO_CodingWMV;
1591 codec_type_parse = CODEC_TYPE_VC1;
1592 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1593 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001594 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1595 OMX_MAX_STRINGNAME_SIZE)) {
1596 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1597 output_capability=V4L2_PIX_FMT_VP8;
1598 eCompressionFormat = OMX_VIDEO_CodingVPX;
1599 codec_type_parse = CODEC_TYPE_VP8;
1600 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001601
Arun Menon906de572013-06-18 17:01:40 -07001602 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001603 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07001604 eRet = OMX_ErrorInvalidComponentName;
1605 }
Arun Menon906de572013-06-18 17:01:40 -07001606 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001607
Arun Menon906de572013-06-18 17:01:40 -07001608 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001609 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1610 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1611 if (!client_buffers.set_color_format(dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001612 DEBUG_PRINT_ERROR("Setting color format failed");
Vinay Kaliada4f4422013-01-09 10:45:03 -08001613 eRet = OMX_ErrorInsufficientResources;
1614 }
1615
Arun Menon906de572013-06-18 17:01:40 -07001616 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001617
Arun Menon906de572013-06-18 17:01:40 -07001618 struct v4l2_capability cap;
1619 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1620 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001621 DEBUG_PRINT_ERROR("Failed to query capabilities");
Arun Menon906de572013-06-18 17:01:40 -07001622 /*TODO: How to handle this case */
1623 } else {
1624 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001625 " version = %d, capabilities = %x", cap.driver, cap.card,
Arun Menon906de572013-06-18 17:01:40 -07001626 cap.bus_info, cap.version, cap.capabilities);
1627 }
1628 ret=0;
1629 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1630 fdesc.index=0;
1631 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001632 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001633 fdesc.pixelformat, fdesc.flags);
1634 fdesc.index++;
1635 }
1636 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1637 fdesc.index=0;
1638 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001639
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001640 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001641 fdesc.pixelformat, fdesc.flags);
1642 fdesc.index++;
1643 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001644 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001645 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1646 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1647 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1648 fmt.fmt.pix_mp.pixelformat = output_capability;
1649 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1650 if (ret) {
1651 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001652 DEBUG_PRINT_ERROR("Failed to set format on output port");
Arun Menon906de572013-06-18 17:01:40 -07001653 return OMX_ErrorInsufficientResources;
1654 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001655 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001656 if (codec_ambiguous) {
1657 if (output_capability == V4L2_PIX_FMT_DIVX) {
1658 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001659
Arun Menon906de572013-06-18 17:01:40 -07001660 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1661 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1662 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1663 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1664 } else {
1665 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1666 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001667
Arun Menon906de572013-06-18 17:01:40 -07001668 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1669 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1670 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001671 DEBUG_PRINT_ERROR("Failed to set divx version");
Arun Menon906de572013-06-18 17:01:40 -07001672 }
1673 } else {
1674 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1675 }
1676 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001677
Jia Meng3a3c6492013-12-19 17:16:52 +08001678 property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
1679 m_conceal_color= atoi(property_value);
1680 DEBUG_PRINT_HIGH("trying to set 0x%x as conceal color\n",m_conceal_color);
1681 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
1682 control.value = m_conceal_color;
1683 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1684 if (ret) {
1685 DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
1686 }
1687
Arun Menon906de572013-06-18 17:01:40 -07001688 //Get the hardware capabilities
1689 memset((void *)&frmsize,0,sizeof(frmsize));
1690 frmsize.index = 0;
1691 frmsize.pixel_format = output_capability;
1692 ret = ioctl(drv_ctx.video_driver_fd,
1693 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1694 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001695 DEBUG_PRINT_ERROR("Failed to get framesizes");
Arun Menon906de572013-06-18 17:01:40 -07001696 return OMX_ErrorHardware;
1697 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001698
Arun Menon906de572013-06-18 17:01:40 -07001699 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1700 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1701 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1702 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1703 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1704 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001705
Arun Menon906de572013-06-18 17:01:40 -07001706 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1707 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1708 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1709 fmt.fmt.pix_mp.pixelformat = capture_capability;
1710 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1711 if (ret) {
1712 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001713 DEBUG_PRINT_ERROR("Failed to set format on capture port");
Arun Menon906de572013-06-18 17:01:40 -07001714 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001715 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001716 if (secure_mode) {
1717 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1718 control.value = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001719 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001720 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1721 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001722 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001723 return OMX_ErrorInsufficientResources;
1724 }
1725 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001726
Arun Menon906de572013-06-18 17:01:40 -07001727 /*Get the Buffer requirements for input and output ports*/
1728 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1729 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1730 if (secure_mode) {
1731 drv_ctx.op_buf.alignment=SZ_1M;
1732 drv_ctx.ip_buf.alignment=SZ_1M;
1733 } else {
1734 drv_ctx.op_buf.alignment=SZ_4K;
1735 drv_ctx.ip_buf.alignment=SZ_4K;
1736 }
1737 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1738 drv_ctx.extradata = 0;
1739 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1740 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1741 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1742 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1743 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001744
Vinay Kalia5713bb32013-01-16 18:39:59 -08001745 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001746#ifdef DEFAULT_EXTRADATA
Arun Menonf8908a62013-12-20 17:36:21 -08001747 if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
1748 OMX_MAX_STRINGNAME_SIZE) && (eRet == OMX_ErrorNone))
1749 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001750#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001751 eRet=get_buffer_req(&drv_ctx.ip_buf);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001752 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
Vinay Kalia5713bb32013-01-16 18:39:59 -08001753 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001754 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1755 if (m_frame_parser.mutils == NULL) {
1756 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001757
Arun Menon906de572013-06-18 17:01:40 -07001758 if (m_frame_parser.mutils == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001759 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001760 eRet = OMX_ErrorInsufficientResources;
1761 } else {
1762 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1763 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1764 h264_scratch.nFilledLen = 0;
1765 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001766
Arun Menon906de572013-06-18 17:01:40 -07001767 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001768 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001769 return OMX_ErrorInsufficientResources;
1770 }
1771 m_frame_parser.mutils->initialize_frame_checking_environment();
1772 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1773 }
1774 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001775
Arun Menon906de572013-06-18 17:01:40 -07001776 h264_parser = new h264_stream_parser();
1777 if (!h264_parser) {
1778 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1779 eRet = OMX_ErrorInsufficientResources;
1780 }
1781 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001782
Arun Menon906de572013-06-18 17:01:40 -07001783 if (pipe(fds)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001784 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001785 eRet = OMX_ErrorInsufficientResources;
1786 } else {
1787 int temp1[2];
1788 if (fds[0] == 0 || fds[1] == 0) {
1789 if (pipe (temp1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001790 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001791 return OMX_ErrorInsufficientResources;
1792 }
1793 //close (fds[0]);
1794 //close (fds[1]);
1795 fds[0] = temp1 [0];
1796 fds[1] = temp1 [1];
1797 }
1798 m_pipe_in = fds[0];
1799 m_pipe_out = fds[1];
1800 msg_thread_created = true;
1801 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001802
Arun Menon906de572013-06-18 17:01:40 -07001803 if (r < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001804 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001805 msg_thread_created = false;
1806 eRet = OMX_ErrorInsufficientResources;
1807 }
1808 }
1809 }
1810
1811 if (eRet != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001812 DEBUG_PRINT_ERROR("Component Init Failed");
Arun Menon906de572013-06-18 17:01:40 -07001813 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001814 DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
Arun Menon906de572013-06-18 17:01:40 -07001815 }
1816 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1817 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001818}
1819
1820/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001821 FUNCTION
1822 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001823
Arun Menon906de572013-06-18 17:01:40 -07001824 DESCRIPTION
1825 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001826
Arun Menon906de572013-06-18 17:01:40 -07001827 PARAMETERS
1828 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001829
Arun Menon906de572013-06-18 17:01:40 -07001830 RETURN VALUE
1831 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001832
Arun Menon906de572013-06-18 17:01:40 -07001833 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001834OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001835(
1836 OMX_IN OMX_HANDLETYPE hComp,
1837 OMX_OUT OMX_STRING componentName,
1838 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1839 OMX_OUT OMX_VERSIONTYPE* specVersion,
1840 OMX_OUT OMX_UUIDTYPE* componentUUID
1841 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001842{
Arun Menon906de572013-06-18 17:01:40 -07001843 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001844 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001845 return OMX_ErrorInvalidState;
1846 }
Arun Menon906de572013-06-18 17:01:40 -07001847 /* TBD -- Return the proper version */
1848 if (specVersion) {
1849 specVersion->nVersion = OMX_SPEC_VERSION;
1850 }
1851 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001852}
1853/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001854 FUNCTION
1855 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001856
Arun Menon906de572013-06-18 17:01:40 -07001857 DESCRIPTION
1858 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001859
Arun Menon906de572013-06-18 17:01:40 -07001860 PARAMETERS
1861 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001862
Arun Menon906de572013-06-18 17:01:40 -07001863 RETURN VALUE
1864 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001865
Arun Menon906de572013-06-18 17:01:40 -07001866 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001867OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001868 OMX_IN OMX_COMMANDTYPE cmd,
1869 OMX_IN OMX_U32 param1,
1870 OMX_IN OMX_PTR cmdData
1871 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001872{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001873 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001874 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001875 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001876 return OMX_ErrorInvalidState;
1877 }
1878 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001879 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001880 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07001881 "to invalid port: %lu", param1);
1882 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001883 }
1884 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1885 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001886 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001887 return OMX_ErrorNone;
1888}
1889
1890/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001891 FUNCTION
1892 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001893
Arun Menon906de572013-06-18 17:01:40 -07001894 DESCRIPTION
1895 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001896
Arun Menon906de572013-06-18 17:01:40 -07001897 PARAMETERS
1898 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001899
Arun Menon906de572013-06-18 17:01:40 -07001900 RETURN VALUE
1901 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001902
Arun Menon906de572013-06-18 17:01:40 -07001903 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001904OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001905 OMX_IN OMX_COMMANDTYPE cmd,
1906 OMX_IN OMX_U32 param1,
1907 OMX_IN OMX_PTR cmdData
1908 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001909{
Arun Menon906de572013-06-18 17:01:40 -07001910 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1911 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1912 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001913
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001914 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
1915 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07001916 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001917
Arun Menon906de572013-06-18 17:01:40 -07001918 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001919 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
1920 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07001921 /***************************/
1922 /* Current State is Loaded */
1923 /***************************/
1924 if (m_state == OMX_StateLoaded) {
1925 if (eState == OMX_StateIdle) {
1926 //if all buffers are allocated or all ports disabled
1927 if (allocate_done() ||
1928 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001929 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07001930 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001931 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07001932 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1933 // Skip the event notification
1934 bFlag = 0;
1935 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001936 }
Arun Menon906de572013-06-18 17:01:40 -07001937 /* Requesting transition from Loaded to Loaded */
1938 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001939 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07001940 post_event(OMX_EventError,OMX_ErrorSameState,\
1941 OMX_COMPONENT_GENERATE_EVENT);
1942 eRet = OMX_ErrorSameState;
1943 }
1944 /* Requesting transition from Loaded to WaitForResources */
1945 else if (eState == OMX_StateWaitForResources) {
1946 /* Since error is None , we will post an event
1947 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001948 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07001949 }
1950 /* Requesting transition from Loaded to Executing */
1951 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001952 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001953 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1954 OMX_COMPONENT_GENERATE_EVENT);
1955 eRet = OMX_ErrorIncorrectStateTransition;
1956 }
1957 /* Requesting transition from Loaded to Pause */
1958 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001959 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07001960 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1961 OMX_COMPONENT_GENERATE_EVENT);
1962 eRet = OMX_ErrorIncorrectStateTransition;
1963 }
1964 /* Requesting transition from Loaded to Invalid */
1965 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001966 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07001967 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1968 eRet = OMX_ErrorInvalidState;
1969 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001970 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07001971 eState);
1972 eRet = OMX_ErrorBadParameter;
1973 }
1974 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001975
Arun Menon906de572013-06-18 17:01:40 -07001976 /***************************/
1977 /* Current State is IDLE */
1978 /***************************/
1979 else if (m_state == OMX_StateIdle) {
1980 if (eState == OMX_StateLoaded) {
1981 if (release_done()) {
1982 /*
1983 Since error is None , we will post an event at the end
1984 of this function definition
1985 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001986 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07001987 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001988 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07001989 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1990 // Skip the event notification
1991 bFlag = 0;
1992 }
1993 }
1994 /* Requesting transition from Idle to Executing */
1995 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001996 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001997 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1998 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001999 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002000 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002001 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07002002 }
2003 /* Requesting transition from Idle to Idle */
2004 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002005 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07002006 post_event(OMX_EventError,OMX_ErrorSameState,\
2007 OMX_COMPONENT_GENERATE_EVENT);
2008 eRet = OMX_ErrorSameState;
2009 }
2010 /* Requesting transition from Idle to WaitForResources */
2011 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002012 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002013 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2014 OMX_COMPONENT_GENERATE_EVENT);
2015 eRet = OMX_ErrorIncorrectStateTransition;
2016 }
2017 /* Requesting transition from Idle to Pause */
2018 else if (eState == OMX_StatePause) {
2019 /*To pause the Video core we need to start the driver*/
2020 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2021 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002022 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002023 omx_report_error ();
2024 eRet = OMX_ErrorHardware;
2025 } else {
2026 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002027 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002028 bFlag = 0;
2029 }
2030 }
2031 /* Requesting transition from Idle to Invalid */
2032 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002033 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002034 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2035 eRet = OMX_ErrorInvalidState;
2036 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002037 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002038 eRet = OMX_ErrorBadParameter;
2039 }
2040 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002041
Arun Menon906de572013-06-18 17:01:40 -07002042 /******************************/
2043 /* Current State is Executing */
2044 /******************************/
2045 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002046 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002047 /* Requesting transition from Executing to Idle */
2048 if (eState == OMX_StateIdle) {
2049 /* Since error is None , we will post an event
2050 at the end of this function definition
2051 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002052 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002053 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2054 if (!sem_posted) {
2055 sem_posted = 1;
2056 sem_post (&m_cmd_lock);
2057 execute_omx_flush(OMX_ALL);
2058 }
2059 bFlag = 0;
2060 }
2061 /* Requesting transition from Executing to Paused */
2062 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002063 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002064 m_state = OMX_StatePause;
2065 bFlag = 1;
2066 }
2067 /* Requesting transition from Executing to Loaded */
2068 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002069 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002070 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2071 OMX_COMPONENT_GENERATE_EVENT);
2072 eRet = OMX_ErrorIncorrectStateTransition;
2073 }
2074 /* Requesting transition from Executing to WaitForResources */
2075 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002076 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002077 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2078 OMX_COMPONENT_GENERATE_EVENT);
2079 eRet = OMX_ErrorIncorrectStateTransition;
2080 }
2081 /* Requesting transition from Executing to Executing */
2082 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002083 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
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 Executing to Invalid */
2089 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002090 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002091 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2092 eRet = OMX_ErrorInvalidState;
2093 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002094 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002095 eRet = OMX_ErrorBadParameter;
2096 }
2097 }
2098 /***************************/
2099 /* Current State is Pause */
2100 /***************************/
2101 else if (m_state == OMX_StatePause) {
2102 /* Requesting transition from Pause to Executing */
2103 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002104 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002105 m_state = OMX_StateExecuting;
2106 bFlag = 1;
2107 }
2108 /* Requesting transition from Pause to Idle */
2109 else if (eState == OMX_StateIdle) {
2110 /* Since error is None , we will post an event
2111 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002112 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002113 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2114 if (!sem_posted) {
2115 sem_posted = 1;
2116 sem_post (&m_cmd_lock);
2117 execute_omx_flush(OMX_ALL);
2118 }
2119 bFlag = 0;
2120 }
2121 /* Requesting transition from Pause to loaded */
2122 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002123 DEBUG_PRINT_ERROR("Pause --> loaded");
Arun Menon906de572013-06-18 17:01:40 -07002124 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2125 OMX_COMPONENT_GENERATE_EVENT);
2126 eRet = OMX_ErrorIncorrectStateTransition;
2127 }
2128 /* Requesting transition from Pause to WaitForResources */
2129 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002130 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002131 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2132 OMX_COMPONENT_GENERATE_EVENT);
2133 eRet = OMX_ErrorIncorrectStateTransition;
2134 }
2135 /* Requesting transition from Pause to Pause */
2136 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002137 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002138 post_event(OMX_EventError,OMX_ErrorSameState,\
2139 OMX_COMPONENT_GENERATE_EVENT);
2140 eRet = OMX_ErrorSameState;
2141 }
2142 /* Requesting transition from Pause to Invalid */
2143 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002144 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002145 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2146 eRet = OMX_ErrorInvalidState;
2147 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002148 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002149 eRet = OMX_ErrorBadParameter;
2150 }
2151 }
2152 /***************************/
2153 /* Current State is WaitForResources */
2154 /***************************/
2155 else if (m_state == OMX_StateWaitForResources) {
2156 /* Requesting transition from WaitForResources to Loaded */
2157 if (eState == OMX_StateLoaded) {
2158 /* Since error is None , we will post an event
2159 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002160 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002161 }
2162 /* Requesting transition from WaitForResources to WaitForResources */
2163 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002164 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002165 post_event(OMX_EventError,OMX_ErrorSameState,
2166 OMX_COMPONENT_GENERATE_EVENT);
2167 eRet = OMX_ErrorSameState;
2168 }
2169 /* Requesting transition from WaitForResources to Executing */
2170 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002171 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002172 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2173 OMX_COMPONENT_GENERATE_EVENT);
2174 eRet = OMX_ErrorIncorrectStateTransition;
2175 }
2176 /* Requesting transition from WaitForResources to Pause */
2177 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002178 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002179 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2180 OMX_COMPONENT_GENERATE_EVENT);
2181 eRet = OMX_ErrorIncorrectStateTransition;
2182 }
2183 /* Requesting transition from WaitForResources to Invalid */
2184 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002185 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002186 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2187 eRet = OMX_ErrorInvalidState;
2188 }
2189 /* Requesting transition from WaitForResources to Loaded -
2190 is NOT tested by Khronos TS */
2191
2192 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002193 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002194 eRet = OMX_ErrorBadParameter;
2195 }
2196 }
2197 /********************************/
2198 /* Current State is Invalid */
2199 /*******************************/
2200 else if (m_state == OMX_StateInvalid) {
2201 /* State Transition from Inavlid to any state */
2202 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2203 || OMX_StateIdle || OMX_StateExecuting
2204 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002205 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002206 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2207 OMX_COMPONENT_GENERATE_EVENT);
2208 eRet = OMX_ErrorInvalidState;
2209 }
2210 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002211 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002212 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002213#ifdef _MSM8974_
2214 send_codec_config();
2215#endif
Arun Menon906de572013-06-18 17:01:40 -07002216 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2217 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2218 }
2219 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2220 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2221 }
2222 if (!sem_posted) {
2223 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002224 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002225 sem_post (&m_cmd_lock);
2226 execute_omx_flush(param1);
2227 }
2228 bFlag = 0;
2229 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002230 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002231 "with param1: %lu", param1);
2232 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2233 m_inp_bEnabled = OMX_TRUE;
2234
2235 if ( (m_state == OMX_StateLoaded &&
2236 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2237 || allocate_input_done()) {
2238 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2239 OMX_COMPONENT_GENERATE_EVENT);
2240 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002241 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002242 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2243 // Skip the event notification
2244 bFlag = 0;
2245 }
2246 }
2247 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002248 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002249 m_out_bEnabled = OMX_TRUE;
2250
2251 if ( (m_state == OMX_StateLoaded &&
2252 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2253 || (allocate_output_done())) {
2254 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2255 OMX_COMPONENT_GENERATE_EVENT);
2256
2257 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002258 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002259 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2260 // Skip the event notification
2261 bFlag = 0;
2262 }
2263 }
2264 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002265 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002266 "with param1: %lu", param1);
2267 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002268 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002269 m_inp_bEnabled = OMX_FALSE;
2270 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2271 && release_input_done()) {
2272 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2273 OMX_COMPONENT_GENERATE_EVENT);
2274 } else {
2275 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2276 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2277 if (!sem_posted) {
2278 sem_posted = 1;
2279 sem_post (&m_cmd_lock);
2280 }
2281 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2282 }
2283
2284 // Skip the event notification
2285 bFlag = 0;
2286 }
2287 }
2288 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2289 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002290 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002291 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2292 && release_output_done()) {
2293 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2294 OMX_COMPONENT_GENERATE_EVENT);
2295 } else {
2296 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2297 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2298 if (!sem_posted) {
2299 sem_posted = 1;
2300 sem_post (&m_cmd_lock);
2301 }
2302 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2303 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2304 }
2305 // Skip the event notification
2306 bFlag = 0;
2307
2308 }
2309 }
2310 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002311 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002312 eRet = OMX_ErrorNotImplemented;
2313 }
2314 if (eRet == OMX_ErrorNone && bFlag) {
2315 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2316 }
2317 if (!sem_posted) {
2318 sem_post(&m_cmd_lock);
2319 }
2320
2321 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002322}
2323
2324/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002325 FUNCTION
2326 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002327
Arun Menon906de572013-06-18 17:01:40 -07002328 DESCRIPTION
2329 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002330
Arun Menon906de572013-06-18 17:01:40 -07002331 PARAMETERS
2332 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002333
Arun Menon906de572013-06-18 17:01:40 -07002334 RETURN VALUE
2335 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002336
Arun Menon906de572013-06-18 17:01:40 -07002337 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002338bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2339{
Arun Menon906de572013-06-18 17:01:40 -07002340 bool bRet = false;
2341 struct v4l2_plane plane;
2342 struct v4l2_buffer v4l2_buf;
2343 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302344 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002345 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2346 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002347
Arun Menon906de572013-06-18 17:01:40 -07002348 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002349
Arun Menon906de572013-06-18 17:01:40 -07002350 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2351 output_flush_progress = true;
2352 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2353 } else {
2354 /* XXX: The driver/hardware does not support flushing of individual ports
2355 * in all states. So we pretty much need to flush both ports internally,
2356 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2357 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2358 * we automatically omit sending the FLUSH done for the "opposite" port. */
2359 input_flush_progress = true;
2360 output_flush_progress = true;
2361 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2362 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002363
Arun Menon906de572013-06-18 17:01:40 -07002364 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002365 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002366 bRet = false;
2367 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002368
Arun Menon906de572013-06-18 17:01:40 -07002369 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002370}
2371/*=========================================================================
2372FUNCTION : execute_output_flush
2373
2374DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002375Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002376
2377PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002378None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002379
2380RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002381true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002382==========================================================================*/
2383bool omx_vdec::execute_output_flush()
2384{
Arun Menon906de572013-06-18 17:01:40 -07002385 unsigned p1 = 0; // Parameter - 1
2386 unsigned p2 = 0; // Parameter - 2
2387 unsigned ident = 0;
2388 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002389
Arun Menon906de572013-06-18 17:01:40 -07002390 /*Generate FBD for all Buffers in the FTBq*/
2391 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002392 DEBUG_PRINT_LOW("Initiate Output Flush");
Arun Menon906de572013-06-18 17:01:40 -07002393 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002394 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002395 m_ftb_q.m_size,pending_output_buffers);
2396 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002397 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002398 if (ident == m_fill_output_msg ) {
2399 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2400 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2401 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2402 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002403 }
Arun Menon906de572013-06-18 17:01:40 -07002404 pthread_mutex_unlock(&m_lock);
2405 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002406
Arun Menon906de572013-06-18 17:01:40 -07002407 if (arbitrary_bytes) {
2408 prev_ts = LLONG_MAX;
2409 rst_prev_ts = true;
2410 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002411 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002412 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002413}
2414/*=========================================================================
2415FUNCTION : execute_input_flush
2416
2417DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002418Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002419
2420PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002421None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002422
2423RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002424true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002425==========================================================================*/
2426bool omx_vdec::execute_input_flush()
2427{
Arun Menon906de572013-06-18 17:01:40 -07002428 unsigned i =0;
2429 unsigned p1 = 0; // Parameter - 1
2430 unsigned p2 = 0; // Parameter - 2
2431 unsigned ident = 0;
2432 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002433
Arun Menon906de572013-06-18 17:01:40 -07002434 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002435 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002436
Arun Menon906de572013-06-18 17:01:40 -07002437 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002438 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002439 while (m_etb_q.m_size) {
2440 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002441
Arun Menon906de572013-06-18 17:01:40 -07002442 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002443 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002444 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2445 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2446 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002447 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002448 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2449 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2450 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002451 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002452 (OMX_BUFFERHEADERTYPE *)p1);
2453 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2454 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002455 }
Arun Menon906de572013-06-18 17:01:40 -07002456 time_stamp_dts.flush_timestamp();
2457 /*Check if Heap Buffers are to be flushed*/
2458 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002459 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002460 h264_scratch.nFilledLen = 0;
2461 nal_count = 0;
2462 look_ahead_nal = false;
2463 frame_count = 0;
2464 h264_last_au_ts = LLONG_MAX;
2465 h264_last_au_flags = 0;
2466 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2467 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002468 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002469 if (m_frame_parser.mutils) {
2470 m_frame_parser.mutils->initialize_frame_checking_environment();
2471 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002472
Arun Menon906de572013-06-18 17:01:40 -07002473 while (m_input_pending_q.m_size) {
2474 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2475 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2476 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002477
Arun Menon906de572013-06-18 17:01:40 -07002478 if (psource_frame) {
2479 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2480 psource_frame = NULL;
2481 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002482
Arun Menon906de572013-06-18 17:01:40 -07002483 if (pdest_frame) {
2484 pdest_frame->nFilledLen = 0;
2485 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2486 (unsigned int)NULL);
2487 pdest_frame = NULL;
2488 }
2489 m_frame_parser.flush();
2490 } else if (codec_config_flag) {
2491 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2492 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002493 }
Arun Menon906de572013-06-18 17:01:40 -07002494 pthread_mutex_unlock(&m_lock);
2495 input_flush_progress = false;
2496 if (!arbitrary_bytes) {
2497 prev_ts = LLONG_MAX;
2498 rst_prev_ts = true;
2499 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002500#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002501 if (m_debug_timestamp) {
2502 m_timestamp_list.reset_ts_list();
2503 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002504#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002505 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002506 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002507}
2508
2509
2510/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002511 FUNCTION
2512 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002513
Arun Menon906de572013-06-18 17:01:40 -07002514 DESCRIPTION
2515 Send the event to decoder pipe. This is needed to generate the callbacks
2516 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002517
Arun Menon906de572013-06-18 17:01:40 -07002518 PARAMETERS
2519 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002520
Arun Menon906de572013-06-18 17:01:40 -07002521 RETURN VALUE
2522 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002523
Arun Menon906de572013-06-18 17:01:40 -07002524 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002525bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002526 unsigned int p2,
2527 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002528{
Arun Menon906de572013-06-18 17:01:40 -07002529 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002530
2531
Arun Menon906de572013-06-18 17:01:40 -07002532 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002533
Arun Menon906de572013-06-18 17:01:40 -07002534 if (id == m_fill_output_msg ||
2535 id == OMX_COMPONENT_GENERATE_FBD) {
2536 m_ftb_q.insert_entry(p1,p2,id);
2537 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2538 id == OMX_COMPONENT_GENERATE_EBD ||
2539 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2540 m_etb_q.insert_entry(p1,p2,id);
2541 } else {
2542 m_cmd_q.insert_entry(p1,p2,id);
2543 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002544
Arun Menon906de572013-06-18 17:01:40 -07002545 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002546 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002547 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002548
Arun Menon906de572013-06-18 17:01:40 -07002549 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002550
Arun Menon906de572013-06-18 17:01:40 -07002551 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002552}
2553
2554OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2555{
Arun Menon906de572013-06-18 17:01:40 -07002556 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2557 if (!profileLevelType)
2558 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002559
Arun Menon906de572013-06-18 17:01:40 -07002560 if (profileLevelType->nPortIndex == 0) {
2561 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2562 if (profileLevelType->nProfileIndex == 0) {
2563 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2564 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002565
Arun Menon906de572013-06-18 17:01:40 -07002566 } else if (profileLevelType->nProfileIndex == 1) {
2567 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2568 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2569 } else if (profileLevelType->nProfileIndex == 2) {
2570 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2571 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2572 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002573 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002574 profileLevelType->nProfileIndex);
2575 eRet = OMX_ErrorNoMore;
2576 }
2577 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2578 if (profileLevelType->nProfileIndex == 0) {
2579 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2580 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2581 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002582 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002583 eRet = OMX_ErrorNoMore;
2584 }
2585 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2586 if (profileLevelType->nProfileIndex == 0) {
2587 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2588 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2589 } else if (profileLevelType->nProfileIndex == 1) {
2590 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2591 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2592 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002593 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002594 eRet = OMX_ErrorNoMore;
2595 }
2596 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2597 eRet = OMX_ErrorNoMore;
2598 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2599 if (profileLevelType->nProfileIndex == 0) {
2600 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2601 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2602 } else if (profileLevelType->nProfileIndex == 1) {
2603 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2604 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2605 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002606 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002607 eRet = OMX_ErrorNoMore;
2608 }
2609 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002610 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002611 eRet = OMX_ErrorNoMore;
2612 }
2613 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002614 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002615 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002616 }
Arun Menon906de572013-06-18 17:01:40 -07002617 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002618}
2619
2620/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002621 FUNCTION
2622 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002623
Arun Menon906de572013-06-18 17:01:40 -07002624 DESCRIPTION
2625 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002626
Arun Menon906de572013-06-18 17:01:40 -07002627 PARAMETERS
2628 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002629
Arun Menon906de572013-06-18 17:01:40 -07002630 RETURN VALUE
2631 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002632
Arun Menon906de572013-06-18 17:01:40 -07002633 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002634OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002635 OMX_IN OMX_INDEXTYPE paramIndex,
2636 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002637{
2638 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2639
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002640 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002641 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002642 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002643 return OMX_ErrorInvalidState;
2644 }
Arun Menon906de572013-06-18 17:01:40 -07002645 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002646 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002647 return OMX_ErrorBadParameter;
2648 }
Arun Menon906de572013-06-18 17:01:40 -07002649 switch ((unsigned long)paramIndex) {
2650 case OMX_IndexParamPortDefinition: {
2651 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2652 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002653 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002654 eRet = update_portdef(portDefn);
2655 if (eRet == OMX_ErrorNone)
2656 m_port_def = *portDefn;
2657 break;
2658 }
2659 case OMX_IndexParamVideoInit: {
2660 OMX_PORT_PARAM_TYPE *portParamType =
2661 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002662 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002663
Arun Menon906de572013-06-18 17:01:40 -07002664 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2665 portParamType->nSize = sizeof(portParamType);
2666 portParamType->nPorts = 2;
2667 portParamType->nStartPortNumber = 0;
2668 break;
2669 }
2670 case OMX_IndexParamVideoPortFormat: {
2671 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2672 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002673 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002674
Arun Menon906de572013-06-18 17:01:40 -07002675 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2676 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002677
Arun Menon906de572013-06-18 17:01:40 -07002678 if (0 == portFmt->nPortIndex) {
2679 if (0 == portFmt->nIndex) {
2680 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2681 portFmt->eCompressionFormat = eCompressionFormat;
2682 } else {
2683 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002684 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002685 eRet = OMX_ErrorNoMore;
2686 }
2687 } else if (1 == portFmt->nPortIndex) {
2688 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002689
Arun Menon906de572013-06-18 17:01:40 -07002690 if (0 == portFmt->nIndex)
2691 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2692 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2693 else if (1 == portFmt->nIndex)
2694 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2695 else {
2696 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002697 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002698 eRet = OMX_ErrorNoMore;
2699 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002700 DEBUG_PRINT_LOW("returning %d", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002701 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002702 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002703 (int)portFmt->nPortIndex);
2704 eRet = OMX_ErrorBadPortIndex;
2705 }
2706 break;
2707 }
2708 /*Component should support this port definition*/
2709 case OMX_IndexParamAudioInit: {
2710 OMX_PORT_PARAM_TYPE *audioPortParamType =
2711 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002712 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002713 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2714 audioPortParamType->nSize = sizeof(audioPortParamType);
2715 audioPortParamType->nPorts = 0;
2716 audioPortParamType->nStartPortNumber = 0;
2717 break;
2718 }
2719 /*Component should support this port definition*/
2720 case OMX_IndexParamImageInit: {
2721 OMX_PORT_PARAM_TYPE *imagePortParamType =
2722 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002723 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002724 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2725 imagePortParamType->nSize = sizeof(imagePortParamType);
2726 imagePortParamType->nPorts = 0;
2727 imagePortParamType->nStartPortNumber = 0;
2728 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002729
Arun Menon906de572013-06-18 17:01:40 -07002730 }
2731 /*Component should support this port definition*/
2732 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002733 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002734 paramIndex);
2735 eRet =OMX_ErrorUnsupportedIndex;
2736 break;
2737 }
2738 case OMX_IndexParamStandardComponentRole: {
2739 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2740 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2741 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2742 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002743
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002744 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002745 paramIndex);
2746 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2747 OMX_MAX_STRINGNAME_SIZE);
2748 break;
2749 }
2750 /* Added for parameter test */
2751 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002752
Arun Menon906de572013-06-18 17:01:40 -07002753 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2754 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002755 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002756 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2757 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002758
Arun Menon906de572013-06-18 17:01:40 -07002759 break;
2760 }
2761 /* Added for parameter test */
2762 case OMX_IndexParamCompBufferSupplier: {
2763 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2764 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002765 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002766
Arun Menon906de572013-06-18 17:01:40 -07002767 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2768 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2769 if (0 == bufferSupplierType->nPortIndex)
2770 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2771 else if (1 == bufferSupplierType->nPortIndex)
2772 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2773 else
2774 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002775
2776
Arun Menon906de572013-06-18 17:01:40 -07002777 break;
2778 }
2779 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002780 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002781 paramIndex);
2782 break;
2783 }
2784 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002785 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002786 paramIndex);
2787 break;
2788 }
2789 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002790 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002791 paramIndex);
2792 break;
2793 }
2794 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002795 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002796 paramIndex);
2797 break;
2798 }
2799 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002800 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002801 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2802 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2803 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2804 break;
2805 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002806#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002807 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002808 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002809 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2810 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002811
Arun Menon906de572013-06-18 17:01:40 -07002812 if (secure_mode) {
2813 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2814 GRALLOC_USAGE_PRIVATE_UNCACHED);
2815 } else {
2816 nativeBuffersUsage->nUsage =
2817 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2818 GRALLOC_USAGE_PRIVATE_UNCACHED);
2819 }
2820 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002821 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002822 eRet = OMX_ErrorBadParameter;
2823 }
2824 }
2825 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002826#endif
2827
Arun Menon906de572013-06-18 17:01:40 -07002828 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002829 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002830 eRet =OMX_ErrorUnsupportedIndex;
2831 }
2832
Shalaj Jain273b3e02012-06-22 19:08:03 -07002833 }
2834
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002835 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07002836 drv_ctx.video_resolution.frame_width,
2837 drv_ctx.video_resolution.frame_height,
2838 drv_ctx.video_resolution.stride,
2839 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002840
Arun Menon906de572013-06-18 17:01:40 -07002841 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002842}
2843
2844#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2845OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2846{
2847 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2848 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2849 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2850
Arun Menon906de572013-06-18 17:01:40 -07002851 if ((params == NULL) ||
2852 (params->nativeBuffer == NULL) ||
2853 (params->nativeBuffer->handle == NULL) ||
2854 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002855 return OMX_ErrorBadParameter;
2856 m_use_android_native_buffers = OMX_TRUE;
2857 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2858 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002859 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 -07002860 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002861 if (!secure_mode) {
2862 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002863 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002864 if (buffer == MAP_FAILED) {
2865 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2866 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002867 }
2868 }
2869 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2870 } else {
2871 eRet = OMX_ErrorBadParameter;
2872 }
2873 return eRet;
2874}
2875#endif
Praveen Chavancf924182013-12-06 23:16:23 -08002876
2877OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
2878 struct v4l2_control control;
2879 struct v4l2_format fmt;
2880 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
2881 control.value = 1;
2882 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2883 if (rc < 0) {
2884 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
2885 return OMX_ErrorHardware;
2886 }
2887 m_smoothstreaming_mode = true;
2888 return OMX_ErrorNone;
2889}
2890
Shalaj Jain273b3e02012-06-22 19:08:03 -07002891/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002892 FUNCTION
2893 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002894
Arun Menon906de572013-06-18 17:01:40 -07002895 DESCRIPTION
2896 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002897
Arun Menon906de572013-06-18 17:01:40 -07002898 PARAMETERS
2899 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002900
Arun Menon906de572013-06-18 17:01:40 -07002901 RETURN VALUE
2902 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002903
Arun Menon906de572013-06-18 17:01:40 -07002904 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002905OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002906 OMX_IN OMX_INDEXTYPE paramIndex,
2907 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002908{
2909 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002910 int ret=0;
2911 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002912 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002913 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002914 return OMX_ErrorInvalidState;
2915 }
Arun Menon906de572013-06-18 17:01:40 -07002916 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002917 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07002918 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002919 }
Arun Menon906de572013-06-18 17:01:40 -07002920 if ((m_state != OMX_StateLoaded) &&
2921 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2922 (m_out_bEnabled == OMX_TRUE) &&
2923 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2924 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002925 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002926 return OMX_ErrorIncorrectStateOperation;
2927 }
Arun Menon906de572013-06-18 17:01:40 -07002928 switch ((unsigned long)paramIndex) {
2929 case OMX_IndexParamPortDefinition: {
2930 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2931 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2932 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2933 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002934 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07002935 (int)portDefn->format.video.nFrameHeight,
2936 (int)portDefn->format.video.nFrameWidth);
2937 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002938 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Arun Menon906de572013-06-18 17:01:40 -07002939 m_display_id = portDefn->format.video.pNativeWindow;
2940 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08002941 /* update output port resolution with client supplied dimensions
2942 in case scaling is enabled, else it follows input resolution set
2943 */
2944 if (is_down_scalar_enabled) {
2945 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07002946 portDefn->format.video.nFrameWidth,
2947 portDefn->format.video.nFrameHeight);
2948 if (portDefn->format.video.nFrameHeight != 0x0 &&
2949 portDefn->format.video.nFrameWidth != 0x0) {
2950 update_resolution(portDefn->format.video.nFrameWidth,
2951 portDefn->format.video.nFrameHeight,
2952 portDefn->format.video.nFrameWidth,
2953 portDefn->format.video.nFrameHeight);
2954 eRet = is_video_session_supported();
2955 if (eRet)
2956 break;
2957 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2958 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2959 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2960 fmt.fmt.pix_mp.pixelformat = capture_capability;
2961 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);
2962 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2963 if (ret) {
2964 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2965 eRet = OMX_ErrorUnsupportedSetting;
2966 } else
2967 eRet = get_buffer_req(&drv_ctx.op_buf);
2968 }
Praveen Chavane78460c2013-12-06 23:16:04 -08002969 }
Arun Menon906de572013-06-18 17:01:40 -07002970 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002971 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07002972 eRet = OMX_ErrorBadParameter;
2973 } else {
2974 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
2975 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
2976 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
2977 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
2978 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
2979 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
2980 drv_ctx.extradata_info.buffer_size;
2981 eRet = set_buffer_req(&drv_ctx.op_buf);
2982 if (eRet == OMX_ErrorNone)
2983 m_port_def = *portDefn;
2984 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002985 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07002986 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
2987 portDefn->nBufferCountActual, portDefn->nBufferSize);
2988 eRet = OMX_ErrorBadParameter;
2989 }
2990 }
2991 } else if (OMX_DirInput == portDefn->eDir) {
2992 bool port_format_changed = false;
2993 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
2994 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
2995 // Frame rate only should be set if this is a "known value" or to
2996 // activate ts prediction logic (arbitrary mode only) sending input
2997 // timestamps with max value (LLONG_MAX).
2998 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
2999 portDefn->format.video.xFramerate >> 16);
3000 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3001 drv_ctx.frame_rate.fps_denominator);
3002 if (!drv_ctx.frame_rate.fps_numerator) {
3003 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3004 drv_ctx.frame_rate.fps_numerator = 30;
3005 }
3006 if (drv_ctx.frame_rate.fps_denominator)
3007 drv_ctx.frame_rate.fps_numerator = (int)
3008 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3009 drv_ctx.frame_rate.fps_denominator = 1;
3010 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3011 drv_ctx.frame_rate.fps_numerator;
3012 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3013 frm_int, drv_ctx.frame_rate.fps_numerator /
3014 (float)drv_ctx.frame_rate.fps_denominator);
3015 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003016 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003017 if (drv_ctx.video_resolution.frame_height !=
3018 portDefn->format.video.nFrameHeight ||
3019 drv_ctx.video_resolution.frame_width !=
3020 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003021 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003022 portDefn->format.video.nFrameWidth,
3023 portDefn->format.video.nFrameHeight);
3024 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003025 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3026 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3027 if (frameHeight != 0x0 && frameWidth != 0x0) {
3028 if (m_smoothstreaming_mode &&
3029 ((frameWidth * frameHeight) <
3030 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3031 frameWidth = m_smoothstreaming_width;
3032 frameHeight = m_smoothstreaming_height;
3033 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3034 frameWidth, frameHeight);
3035 }
3036 update_resolution(frameWidth, frameHeight,
3037 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003038 eRet = is_video_session_supported();
3039 if (eRet)
3040 break;
3041 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3042 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3043 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3044 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003045 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 -07003046 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3047 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003048 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003049 eRet = OMX_ErrorUnsupportedSetting;
3050 } else
3051 eRet = get_buffer_req(&drv_ctx.op_buf);
3052 }
3053 }
3054 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3055 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3056 port_format_changed = true;
3057 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3058 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3059 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3060 (~(buffer_prop->alignment - 1));
3061 eRet = set_buffer_req(buffer_prop);
3062 }
3063 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003064 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003065 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3066 portDefn->nBufferCountActual, portDefn->nBufferSize);
3067 eRet = OMX_ErrorBadParameter;
3068 }
3069 } else if (portDefn->eDir == OMX_DirMax) {
3070 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3071 (int)portDefn->nPortIndex);
3072 eRet = OMX_ErrorBadPortIndex;
3073 }
3074 }
3075 break;
3076 case OMX_IndexParamVideoPortFormat: {
3077 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3078 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3079 int ret=0;
3080 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003081 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003082 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003083
Arun Menon906de572013-06-18 17:01:40 -07003084 if (1 == portFmt->nPortIndex) {
3085 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3086 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3087 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3088 fmt.fmt.pix_mp.pixelformat = capture_capability;
3089 enum vdec_output_fromat op_format;
3090 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3091 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
3092 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
3093 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
3094 else if (portFmt->eColorFormat ==
3095 (OMX_COLOR_FORMATTYPE)
3096 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3097 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3098 else
3099 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003100
Arun Menon906de572013-06-18 17:01:40 -07003101 if (eRet == OMX_ErrorNone) {
3102 drv_ctx.output_format = op_format;
3103 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3104 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003105 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003106 eRet = OMX_ErrorUnsupportedSetting;
3107 /*TODO: How to handle this case */
3108 } else {
3109 eRet = get_buffer_req(&drv_ctx.op_buf);
3110 }
3111 }
3112 if (eRet == OMX_ErrorNone) {
3113 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003114 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003115 eRet = OMX_ErrorBadParameter;
3116 }
3117 }
3118 }
3119 }
3120 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003121
Arun Menon906de572013-06-18 17:01:40 -07003122 case OMX_QcomIndexPortDefn: {
3123 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3124 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003125 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003126 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003127
Arun Menon906de572013-06-18 17:01:40 -07003128 /* Input port */
3129 if (portFmt->nPortIndex == 0) {
3130 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3131 if (secure_mode) {
3132 arbitrary_bytes = false;
3133 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3134 eRet = OMX_ErrorUnsupportedSetting;
3135 } else {
3136 arbitrary_bytes = true;
3137 }
3138 } else if (portFmt->nFramePackingFormat ==
3139 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3140 arbitrary_bytes = false;
3141 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003142 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003143 portFmt->nFramePackingFormat);
3144 eRet = OMX_ErrorUnsupportedSetting;
3145 }
3146 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003147 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003148 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3149 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3150 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3151 m_out_mem_region_smi = OMX_TRUE;
3152 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003153 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003154 m_use_output_pmem = OMX_TRUE;
3155 }
3156 }
3157 }
3158 }
3159 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003160
Arun Menon906de572013-06-18 17:01:40 -07003161 case OMX_IndexParamStandardComponentRole: {
3162 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3163 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003164 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003165 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003166
Arun Menon906de572013-06-18 17:01:40 -07003167 if ((m_state == OMX_StateLoaded)&&
3168 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3169 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3170 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003171 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003172 return OMX_ErrorIncorrectStateOperation;
3173 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003174
Arun Menon906de572013-06-18 17:01:40 -07003175 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3176 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3177 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3178 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003179 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003180 eRet =OMX_ErrorUnsupportedSetting;
3181 }
3182 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3183 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3184 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3185 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003186 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003187 eRet = OMX_ErrorUnsupportedSetting;
3188 }
3189 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3190 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3191 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3192 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003193 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003194 eRet =OMX_ErrorUnsupportedSetting;
3195 }
3196 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3197 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3198 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3199 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003200 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003201 eRet = OMX_ErrorUnsupportedSetting;
3202 }
3203 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3204 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3205 ) {
3206 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3207 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3208 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003209 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003210 eRet =OMX_ErrorUnsupportedSetting;
3211 }
3212 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3213 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3214 ) {
3215 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3216 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3217 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003218 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003219 eRet =OMX_ErrorUnsupportedSetting;
3220 }
3221 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3222 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3223 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3224 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3225 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003226 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003227 eRet = OMX_ErrorUnsupportedSetting;
3228 }
3229 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003230 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003231 eRet = OMX_ErrorInvalidComponentName;
3232 }
3233 break;
3234 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003235
Arun Menon906de572013-06-18 17:01:40 -07003236 case OMX_IndexParamPriorityMgmt: {
3237 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003238 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003239 return OMX_ErrorIncorrectStateOperation;
3240 }
3241 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003242 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003243 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003244
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003245 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003246 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003247
Arun Menon906de572013-06-18 17:01:40 -07003248 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3249 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003250
Arun Menon906de572013-06-18 17:01:40 -07003251 break;
3252 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003253
Arun Menon906de572013-06-18 17:01:40 -07003254 case OMX_IndexParamCompBufferSupplier: {
3255 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003256 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003257 bufferSupplierType->eBufferSupplier);
3258 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3259 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003260
Arun Menon906de572013-06-18 17:01:40 -07003261 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003262
Arun Menon906de572013-06-18 17:01:40 -07003263 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003264
Arun Menon906de572013-06-18 17:01:40 -07003265 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003266
Arun Menon906de572013-06-18 17:01:40 -07003267 }
3268 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003269 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003270 paramIndex);
3271 break;
3272 }
3273 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003274 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003275 paramIndex);
3276 break;
3277 }
3278 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003279 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003280 paramIndex);
3281 break;
3282 }
3283 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003284 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003285 paramIndex);
3286 break;
3287 }
3288 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3289 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3290 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3291 struct v4l2_control control;
3292 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003293 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003294 pictureOrder->eOutputPictureOrder);
3295 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3296 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3297 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3298 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3299 time_stamp_dts.set_timestamp_reorder_mode(false);
3300 } else
3301 eRet = OMX_ErrorBadParameter;
3302 if (eRet == OMX_ErrorNone) {
3303 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3304 control.value = pic_order;
3305 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3306 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003307 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003308 eRet = OMX_ErrorUnsupportedSetting;
3309 }
3310 }
3311 break;
3312 }
3313 case OMX_QcomIndexParamConcealMBMapExtraData:
3314 if (!secure_mode)
3315 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3316 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3317 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003318 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003319 eRet = OMX_ErrorUnsupportedSetting;
3320 }
3321 break;
3322 case OMX_QcomIndexParamFrameInfoExtraData: {
3323 if (!secure_mode)
3324 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3325 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3326 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003327 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003328 eRet = OMX_ErrorUnsupportedSetting;
3329 }
3330 break;
3331 }
3332 case OMX_QcomIndexParamInterlaceExtraData:
3333 if (!secure_mode)
3334 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3335 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3336 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003337 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003338 eRet = OMX_ErrorUnsupportedSetting;
3339 }
3340 break;
3341 case OMX_QcomIndexParamH264TimeInfo:
3342 if (!secure_mode)
3343 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3344 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3345 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003346 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003347 eRet = OMX_ErrorUnsupportedSetting;
3348 }
3349 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303350 case OMX_QcomIndexParamVideoFramePackingExtradata:
3351 if (!secure_mode)
3352 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3353 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3354 else {
3355 DEBUG_PRINT_ERROR("\n Setting extradata in secure mode is not supported");
3356 eRet = OMX_ErrorUnsupportedSetting;
3357 }
3358 break;
Arun Menon906de572013-06-18 17:01:40 -07003359 case OMX_QcomIndexParamVideoDivx: {
3360 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3361 }
3362 break;
3363 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003364 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003365 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3366 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3367 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3368 eRet = OMX_ErrorUnsupportedSetting;
3369 } else {
3370 m_out_pvt_entry_pmem = OMX_TRUE;
3371 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003372 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003373 m_use_output_pmem = OMX_TRUE;
3374 }
3375 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003376
Arun Menon906de572013-06-18 17:01:40 -07003377 }
3378 break;
3379 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3380 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3381 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3382 struct v4l2_control control;
3383 int rc;
3384 drv_ctx.idr_only_decoding = 1;
3385 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3386 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3387 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3388 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003389 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003390 eRet = OMX_ErrorUnsupportedSetting;
3391 } else {
3392 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3393 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3394 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3395 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003396 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003397 eRet = OMX_ErrorUnsupportedSetting;
3398 }
3399 /*Setting sync frame decoding on driver might change buffer
3400 * requirements so update them here*/
3401 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003402 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003403 eRet = OMX_ErrorUnsupportedSetting;
3404 }
3405 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003406 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003407 eRet = OMX_ErrorUnsupportedSetting;
3408 }
3409 }
3410 }
3411 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003412
Arun Menon906de572013-06-18 17:01:40 -07003413 case OMX_QcomIndexParamIndexExtraDataType: {
3414 if (!secure_mode) {
3415 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3416 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3417 (extradataIndexType->bEnabled == OMX_TRUE) &&
3418 (extradataIndexType->nPortIndex == 1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003419 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
Arun Menon906de572013-06-18 17:01:40 -07003420 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003421
Arun Menon906de572013-06-18 17:01:40 -07003422 }
3423 }
3424 }
3425 break;
3426 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003427#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003428 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003429#else
Arun Menon906de572013-06-18 17:01:40 -07003430 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003431#endif
Arun Menon906de572013-06-18 17:01:40 -07003432 }
3433 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003434#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003435 /* Need to allow following two set_parameters even in Idle
3436 * state. This is ANDROID architecture which is not in sync
3437 * with openmax standard. */
3438 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3439 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3440 if (enableNativeBuffers) {
3441 m_enable_android_native_buffers = enableNativeBuffers->enable;
3442 }
3443 }
3444 break;
3445 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3446 eRet = use_android_native_buffer(hComp, paramData);
3447 }
3448 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003449#endif
Arun Menon906de572013-06-18 17:01:40 -07003450 case OMX_QcomIndexParamEnableTimeStampReorder: {
3451 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3452 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3453 if (reorder->bEnable == OMX_TRUE) {
3454 frm_int =0;
3455 time_stamp_dts.set_timestamp_reorder_mode(true);
3456 } else
3457 time_stamp_dts.set_timestamp_reorder_mode(false);
3458 } else {
3459 time_stamp_dts.set_timestamp_reorder_mode(false);
3460 if (reorder->bEnable == OMX_TRUE) {
3461 eRet = OMX_ErrorUnsupportedSetting;
3462 }
3463 }
3464 }
3465 break;
3466 case OMX_IndexParamVideoProfileLevelCurrent: {
3467 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3468 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3469 if (pParam) {
3470 m_profile_lvl.eProfile = pParam->eProfile;
3471 m_profile_lvl.eLevel = pParam->eLevel;
3472 }
3473 break;
Arun Menon888aa852013-05-30 11:24:42 -07003474
Arun Menon906de572013-06-18 17:01:40 -07003475 }
Arun Menone5652482013-08-04 13:33:05 -07003476 case OMX_QcomIndexParamVideoMetaBufferMode:
3477 {
3478 StoreMetaDataInBuffersParams *metabuffer =
3479 (StoreMetaDataInBuffersParams *)paramData;
3480 if (!metabuffer) {
3481 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3482 eRet = OMX_ErrorBadParameter;
3483 break;
3484 }
3485 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3486 //set property dynamic buffer mode to driver.
3487 struct v4l2_control control;
3488 struct v4l2_format fmt;
3489 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3490 if (metabuffer->bStoreMetaData == true) {
3491 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3492 } else {
3493 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3494 }
3495 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3496 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003497 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003498 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003499 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003500 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003501 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003502 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3503 eRet = OMX_ErrorUnsupportedSetting;
3504 }
3505 } else {
3506 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003507 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003508 metabuffer->nPortIndex);
3509 eRet = OMX_ErrorUnsupportedSetting;
3510 }
3511 break;
3512 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003513 case OMX_QcomIndexParamVideoDownScalar: {
3514 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3515 struct v4l2_control control;
3516 int rc;
3517 if (pParam) {
3518 is_down_scalar_enabled = pParam->bEnable;
3519 if (is_down_scalar_enabled) {
3520 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3521 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3522 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3523 pParam->bEnable);
3524 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3525 if (rc < 0) {
3526 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3527 eRet = OMX_ErrorUnsupportedSetting;
3528 }
3529 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3530 control.value = 1;
3531 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3532 if (rc < 0) {
3533 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3534 eRet = OMX_ErrorUnsupportedSetting;
3535 }
3536 }
3537 }
3538 break;
3539 }
Praveen Chavancf924182013-12-06 23:16:23 -08003540#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3541 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3542 {
3543 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3544 PrepareForAdaptivePlaybackParams* pParams =
3545 (PrepareForAdaptivePlaybackParams *) paramData;
3546 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3547 if (!pParams->bEnable) {
3548 return OMX_ErrorNone;
3549 }
3550 if (pParams->nMaxFrameWidth > kMaxSmoothStreamingWidth
3551 || pParams->nMaxFrameHeight > kMaxSmoothStreamingHeight) {
3552 DEBUG_PRINT_ERROR(
3553 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3554 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
3555 kMaxSmoothStreamingWidth, kMaxSmoothStreamingHeight);
3556 eRet = OMX_ErrorBadParameter;
3557 } else {
3558 eRet = enable_smoothstreaming();
3559 if (eRet != OMX_ErrorNone) {
3560 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver.");
3561 eRet = OMX_ErrorHardware;
3562 } else {
3563 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
3564 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3565 m_smoothstreaming_mode = true;
3566 m_smoothstreaming_width = pParams->nMaxFrameWidth;
3567 m_smoothstreaming_height = pParams->nMaxFrameHeight;
3568 }
3569 }
3570 } else {
3571 DEBUG_PRINT_ERROR(
3572 "Prepare for adaptive playback supported only on output port");
3573 eRet = OMX_ErrorBadParameter;
3574 }
3575 break;
3576 }
3577
3578#endif
Arun Menon906de572013-06-18 17:01:40 -07003579 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003580 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003581 eRet = OMX_ErrorUnsupportedIndex;
3582 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003583 }
Arun Menon906de572013-06-18 17:01:40 -07003584 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003585}
3586
3587/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003588 FUNCTION
3589 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003590
Arun Menon906de572013-06-18 17:01:40 -07003591 DESCRIPTION
3592 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003593
Arun Menon906de572013-06-18 17:01:40 -07003594 PARAMETERS
3595 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003596
Arun Menon906de572013-06-18 17:01:40 -07003597 RETURN VALUE
3598 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003599
Arun Menon906de572013-06-18 17:01:40 -07003600 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003601OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003602 OMX_IN OMX_INDEXTYPE configIndex,
3603 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003604{
Arun Menon906de572013-06-18 17:01:40 -07003605 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003606
Arun Menon906de572013-06-18 17:01:40 -07003607 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003608 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003609 return OMX_ErrorInvalidState;
3610 }
Arun Menon906de572013-06-18 17:01:40 -07003611
3612 switch ((unsigned long)configIndex) {
3613 case OMX_QcomIndexConfigInterlaced: {
3614 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3615 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3616 if (configFmt->nPortIndex == 1) {
3617 if (configFmt->nIndex == 0) {
3618 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3619 } else if (configFmt->nIndex == 1) {
3620 configFmt->eInterlaceType =
3621 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3622 } else if (configFmt->nIndex == 2) {
3623 configFmt->eInterlaceType =
3624 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3625 } else {
3626 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003627 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003628 eRet = OMX_ErrorNoMore;
3629 }
3630
3631 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003632 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003633 (int)configFmt->nPortIndex);
3634 eRet = OMX_ErrorBadPortIndex;
3635 }
3636 break;
3637 }
3638 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3639 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3640 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3641 decoderinstances->nNumOfInstances = 16;
3642 /*TODO: How to handle this case */
3643 break;
3644 }
3645 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3646 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3647 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3648 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303649 memcpy(configFmt, &m_frame_pack_arrangement,
3650 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003651 } else {
3652 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3653 }
3654 break;
3655 }
3656 case OMX_IndexConfigCommonOutputCrop: {
3657 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3658 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3659 break;
3660 }
3661 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003662 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003663 eRet = OMX_ErrorBadParameter;
3664 }
3665
Shalaj Jain273b3e02012-06-22 19:08:03 -07003666 }
Arun Menon906de572013-06-18 17:01:40 -07003667
3668 return eRet;
3669}
3670
3671/* ======================================================================
3672 FUNCTION
3673 omx_vdec::SetConfig
3674
3675 DESCRIPTION
3676 OMX Set Config method implementation
3677
3678 PARAMETERS
3679 <TBD>.
3680
3681 RETURN VALUE
3682 OMX Error None if successful.
3683 ========================================================================== */
3684OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3685 OMX_IN OMX_INDEXTYPE configIndex,
3686 OMX_IN OMX_PTR configData)
3687{
3688 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003689 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003690 return OMX_ErrorInvalidState;
3691 }
3692
3693 OMX_ERRORTYPE ret = OMX_ErrorNone;
3694 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3695
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003696 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003697
3698 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3699 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003700 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003701 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003702 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003703 OMX_U32 extra_size;
3704 // Parsing done here for the AVC atom is definitely not generic
3705 // Currently this piece of code is working, but certainly
3706 // not tested with all .mp4 files.
3707 // Incase of failure, we might need to revisit this
3708 // for a generic piece of code.
3709
3710 // Retrieve size of NAL length field
3711 // byte #4 contains the size of NAL lenght field
3712 nal_length = (config->pData[4] & 0x03) + 1;
3713
3714 extra_size = 0;
3715 if (nal_length > 2) {
3716 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3717 extra_size = (nal_length - 2) * 2;
3718 }
3719
3720 // SPS starts from byte #6
3721 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3722 OMX_U8 *pDestBuf;
3723 m_vendor_config.nPortIndex = config->nPortIndex;
3724
3725 // minus 6 --> SPS starts from byte #6
3726 // minus 1 --> picture param set byte to be ignored from avcatom
3727 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3728 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3729 OMX_U32 len;
3730 OMX_U8 index = 0;
3731 // case where SPS+PPS is sent as part of set_config
3732 pDestBuf = m_vendor_config.pData;
3733
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003734 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003735 m_vendor_config.nPortIndex,
3736 m_vendor_config.nDataSize,
3737 m_vendor_config.pData);
3738 while (index < 2) {
3739 uint8 *psize;
3740 len = *pSrcBuf;
3741 len = len << 8;
3742 len |= *(pSrcBuf + 1);
3743 psize = (uint8 *) & len;
3744 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3745 for (unsigned int i = 0; i < nal_length; i++) {
3746 pDestBuf[i] = psize[nal_length - 1 - i];
3747 }
3748 //memcpy(pDestBuf,pSrcBuf,(len+2));
3749 pDestBuf += len + nal_length;
3750 pSrcBuf += len + 2;
3751 index++;
3752 pSrcBuf++; // skip picture param set
3753 len = 0;
3754 }
3755 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3756 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3757 m_vendor_config.nPortIndex = config->nPortIndex;
3758 m_vendor_config.nDataSize = config->nDataSize;
3759 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3760 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3761 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3762 if (m_vendor_config.pData) {
3763 free(m_vendor_config.pData);
3764 m_vendor_config.pData = NULL;
3765 m_vendor_config.nDataSize = 0;
3766 }
3767
3768 if (((*((OMX_U32 *) config->pData)) &
3769 VC1_SP_MP_START_CODE_MASK) ==
3770 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003771 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07003772 m_vendor_config.nPortIndex = config->nPortIndex;
3773 m_vendor_config.nDataSize = config->nDataSize;
3774 m_vendor_config.pData =
3775 (OMX_U8 *) malloc(config->nDataSize);
3776 memcpy(m_vendor_config.pData, config->pData,
3777 config->nDataSize);
3778 m_vc1_profile = VC1_SP_MP_RCV;
3779 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003780 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07003781 m_vendor_config.nPortIndex = config->nPortIndex;
3782 m_vendor_config.nDataSize = config->nDataSize;
3783 m_vendor_config.pData =
3784 (OMX_U8 *) malloc((config->nDataSize));
3785 memcpy(m_vendor_config.pData, config->pData,
3786 config->nDataSize);
3787 m_vc1_profile = VC1_AP;
3788 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003789 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07003790 m_vendor_config.nPortIndex = config->nPortIndex;
3791 m_vendor_config.nDataSize = config->nDataSize;
3792 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3793 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3794 m_vc1_profile = VC1_SP_MP_RCV;
3795 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003796 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07003797 }
3798 }
3799 return ret;
3800 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3801 struct v4l2_control temp;
3802 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3803
3804 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3805 switch (pNal->nNaluBytes) {
3806 case 0:
3807 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3808 break;
3809 case 2:
3810 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3811 break;
3812 case 4:
3813 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3814 break;
3815 default:
3816 return OMX_ErrorUnsupportedSetting;
3817 }
3818
3819 if (!arbitrary_bytes) {
3820 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3821 * with start code, so only need to notify driver in frame by frame mode */
3822 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3823 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3824 return OMX_ErrorHardware;
3825 }
3826 }
3827
3828 nal_length = pNal->nNaluBytes;
3829 m_frame_parser.init_nal_length(nal_length);
3830
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003831 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07003832 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05303833 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07003834 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05303835 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07003836
3837 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3838 if (config->bEnabled) {
3839 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05303840 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07003841 config->nFps >> 16);
3842 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3843 drv_ctx.frame_rate.fps_denominator);
3844
3845 if (!drv_ctx.frame_rate.fps_numerator) {
3846 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3847 drv_ctx.frame_rate.fps_numerator = 30;
3848 }
3849
3850 if (drv_ctx.frame_rate.fps_denominator) {
3851 drv_ctx.frame_rate.fps_numerator = (int)
3852 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3853 }
3854
3855 drv_ctx.frame_rate.fps_denominator = 1;
3856 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3857 drv_ctx.frame_rate.fps_numerator;
3858
3859 struct v4l2_outputparm oparm;
3860 /*XXX: we're providing timing info as seconds per frame rather than frames
3861 * per second.*/
3862 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3863 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3864
3865 struct v4l2_streamparm sparm;
3866 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3867 sparm.parm.output = oparm;
3868 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3869 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3870 performance might be affected");
3871 ret = OMX_ErrorHardware;
3872 }
3873 client_set_fps = true;
3874 } else {
3875 DEBUG_PRINT_ERROR("Frame rate not supported.");
3876 ret = OMX_ErrorUnsupportedSetting;
3877 }
3878 } else {
3879 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3880 client_set_fps = false;
3881 }
3882 } else {
3883 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3884 (int)config->nPortIndex);
3885 ret = OMX_ErrorBadPortIndex;
3886 }
3887
3888 return ret;
3889 }
3890
3891 return OMX_ErrorNotImplemented;
3892}
3893
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303894#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
3895
Arun Menon906de572013-06-18 17:01:40 -07003896/* ======================================================================
3897 FUNCTION
3898 omx_vdec::GetExtensionIndex
3899
3900 DESCRIPTION
3901 OMX GetExtensionIndex method implementaion. <TBD>
3902
3903 PARAMETERS
3904 <TBD>.
3905
3906 RETURN VALUE
3907 OMX Error None if everything successful.
3908
3909 ========================================================================== */
3910OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3911 OMX_IN OMX_STRING paramName,
3912 OMX_OUT OMX_INDEXTYPE* indexType)
3913{
3914 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003915 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003916 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303917 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07003918 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303919 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003920 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303921 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
3922 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
3923 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
3924 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003925 }
3926#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303927 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003928 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303929 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003930 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303931 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003932 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003933 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303934 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003935 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3936 }
3937#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303938 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07003939 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
3940 }
Praveen Chavancf924182013-12-06 23:16:23 -08003941#if ADAPTIVE_PLAYBACK_SUPPORTED
3942 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
3943 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
3944 }
3945#endif
Arun Menon906de572013-06-18 17:01:40 -07003946 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003947 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003948 return OMX_ErrorNotImplemented;
3949 }
3950 return OMX_ErrorNone;
3951}
3952
3953/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003954 FUNCTION
3955 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07003956
Arun Menon906de572013-06-18 17:01:40 -07003957 DESCRIPTION
3958 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003959
Arun Menon906de572013-06-18 17:01:40 -07003960 PARAMETERS
3961 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003962
Arun Menon906de572013-06-18 17:01:40 -07003963 RETURN VALUE
3964 Error None if everything is successful.
3965 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003966OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003967 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003968{
Arun Menon906de572013-06-18 17:01:40 -07003969 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003970 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07003971 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003972}
3973
3974/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003975 FUNCTION
3976 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07003977
Arun Menon906de572013-06-18 17:01:40 -07003978 DESCRIPTION
3979 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003980
Arun Menon906de572013-06-18 17:01:40 -07003981 PARAMETERS
3982 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003983
Arun Menon906de572013-06-18 17:01:40 -07003984 RETURN VALUE
3985 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003986
Arun Menon906de572013-06-18 17:01:40 -07003987 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003988OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003989 OMX_IN OMX_U32 port,
3990 OMX_IN OMX_HANDLETYPE peerComponent,
3991 OMX_IN OMX_U32 peerPort,
3992 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003993{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003994 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07003995 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003996}
3997
3998/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003999 FUNCTION
4000 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004001
Arun Menon906de572013-06-18 17:01:40 -07004002 DESCRIPTION
4003 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004004
Arun Menon906de572013-06-18 17:01:40 -07004005 PARAMETERS
4006 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004007
Arun Menon906de572013-06-18 17:01:40 -07004008 RETURN VALUE
4009 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004010
Arun Menon906de572013-06-18 17:01:40 -07004011 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004012OMX_ERRORTYPE omx_vdec::allocate_extradata()
4013{
4014#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004015 if (drv_ctx.extradata_info.buffer_size) {
4016 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4017 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4018 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4019 free_ion_memory(&drv_ctx.extradata_info.ion);
Praveen Chavan61e5d162013-11-01 02:49:19 -07004020 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Arun Menon906de572013-06-18 17:01:40 -07004021 }
4022 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4023 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4024 drv_ctx.extradata_info.size, 4096,
4025 &drv_ctx.extradata_info.ion.ion_alloc_data,
4026 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4027 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004028 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004029 return OMX_ErrorInsufficientResources;
4030 }
4031 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4032 drv_ctx.extradata_info.size,
4033 PROT_READ|PROT_WRITE, MAP_SHARED,
4034 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4035 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004036 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004037 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4038 free_ion_memory(&drv_ctx.extradata_info.ion);
4039 return OMX_ErrorInsufficientResources;
4040 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004041 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004042#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304043 if (!m_other_extradata) {
4044 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4045 if (!m_other_extradata) {
4046 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4047 return OMX_ErrorInsufficientResources;
4048 }
4049 }
Arun Menon906de572013-06-18 17:01:40 -07004050 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004051}
4052
Arun Menon906de572013-06-18 17:01:40 -07004053void omx_vdec::free_extradata()
4054{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004055#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004056 if (drv_ctx.extradata_info.uaddr) {
4057 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4058 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4059 free_ion_memory(&drv_ctx.extradata_info.ion);
4060 }
4061 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004062#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304063 if (m_other_extradata) {
4064 free(m_other_extradata);
4065 m_other_extradata = NULL;
4066 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004067}
4068
Shalaj Jain273b3e02012-06-22 19:08:03 -07004069OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004070 OMX_IN OMX_HANDLETYPE hComp,
4071 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4072 OMX_IN OMX_U32 port,
4073 OMX_IN OMX_PTR appData,
4074 OMX_IN OMX_U32 bytes,
4075 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004076{
Arun Menon906de572013-06-18 17:01:40 -07004077 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4078 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4079 unsigned i= 0; // Temporary counter
4080 struct vdec_setbuffer_cmd setbuffers;
4081 OMX_PTR privateAppData = NULL;
4082 private_handle_t *handle = NULL;
4083 OMX_U8 *buff = buffer;
4084 struct v4l2_buffer buf;
4085 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4086 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004087
Arun Menon906de572013-06-18 17:01:40 -07004088 if (!m_out_mem_ptr) {
4089 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4090 eRet = allocate_output_headers();
4091 if (eRet == OMX_ErrorNone)
4092 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004093 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004094
Arun Menon906de572013-06-18 17:01:40 -07004095 if (eRet == OMX_ErrorNone) {
4096 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4097 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4098 break;
4099 }
4100 }
4101 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004102
Arun Menon906de572013-06-18 17:01:40 -07004103 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004104 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004105 eRet = OMX_ErrorInsufficientResources;
4106 }
4107
Arun Menonbdb80b02013-08-12 17:45:54 -07004108 if (dynamic_buf_mode) {
4109 *bufferHdr = (m_out_mem_ptr + i );
4110 (*bufferHdr)->pBuffer = NULL;
4111 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4112 enum v4l2_buf_type buf_type;
4113 int rr = 0;
4114 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4115 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4116 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4117 return OMX_ErrorInsufficientResources;
4118 } else {
4119 streaming[CAPTURE_PORT] = true;
4120 DEBUG_PRINT_LOW("STREAMON Successful");
4121 }
4122 }
4123 BITMASK_SET(&m_out_bm_count,i);
4124 (*bufferHdr)->pAppPrivate = appData;
4125 (*bufferHdr)->pBuffer = buffer;
4126 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4127 return eRet;
4128 }
Arun Menon906de572013-06-18 17:01:40 -07004129 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004130#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004131 if (m_enable_android_native_buffers) {
4132 if (m_use_android_native_buffers) {
4133 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4134 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4135 handle = (private_handle_t *)nBuf->handle;
4136 privateAppData = params->pAppPrivate;
4137 } else {
4138 handle = (private_handle_t *)buff;
4139 privateAppData = appData;
4140 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004141
Arun Menon906de572013-06-18 17:01:40 -07004142 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4143 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4144 " expected %u, got %lu",
4145 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4146 return OMX_ErrorBadParameter;
4147 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004148
Arun Menon906de572013-06-18 17:01:40 -07004149 if (!m_use_android_native_buffers) {
4150 if (!secure_mode) {
4151 buff = (OMX_U8*)mmap(0, handle->size,
4152 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4153 if (buff == MAP_FAILED) {
4154 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4155 return OMX_ErrorInsufficientResources;
4156 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004157 }
4158 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004159#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004160 native_buffer[i].nativehandle = handle;
4161 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004162#endif
Arun Menon906de572013-06-18 17:01:40 -07004163 if (!handle) {
4164 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4165 return OMX_ErrorBadParameter;
4166 }
4167 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4168 drv_ctx.ptr_outputbuffer[i].offset = 0;
4169 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4170 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4171 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4172 } else
4173#endif
4174
4175 if (!ouput_egl_buffers && !m_use_output_pmem) {
4176#ifdef USE_ION
4177 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4178 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4179 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4180 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4181 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004182 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 -07004183 return OMX_ErrorInsufficientResources;
4184 }
4185 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4186 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4187#else
4188 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4189 open (MEM_DEVICE,O_RDWR);
4190
4191 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004192 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004193 return OMX_ErrorInsufficientResources;
4194 }
4195
4196 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4197 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4198 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4199 open (MEM_DEVICE,O_RDWR);
4200 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004201 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004202 return OMX_ErrorInsufficientResources;
4203 }
4204 }
4205
4206 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4207 drv_ctx.op_buf.buffer_size,
4208 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004209 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004210 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4211 return OMX_ErrorInsufficientResources;
4212 }
4213#endif
4214 if (!secure_mode) {
4215 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4216 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4217 PROT_READ|PROT_WRITE, MAP_SHARED,
4218 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4219 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4220 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4221#ifdef USE_ION
4222 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4223#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004224 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004225 return OMX_ErrorInsufficientResources;
4226 }
4227 }
4228 drv_ctx.ptr_outputbuffer[i].offset = 0;
4229 privateAppData = appData;
4230 } else {
4231
4232 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4233 if (!appData || !bytes ) {
4234 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004235 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004236 return OMX_ErrorBadParameter;
4237 }
4238 }
4239
4240 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4241 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4242 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4243 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4244 !pmem_list->nEntries ||
4245 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004246 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004247 return OMX_ErrorBadParameter;
4248 }
4249 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4250 pmem_list->entryList->entry;
4251 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4252 pmem_info->pmem_fd);
4253 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4254 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4255 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4256 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4257 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4258 privateAppData = appData;
4259 }
4260 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4261 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304262 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4263 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4264 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004265
4266 *bufferHdr = (m_out_mem_ptr + i );
4267 if (secure_mode)
4268 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4269 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4270 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4271 sizeof (vdec_bufferpayload));
4272
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004273 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004274 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4275 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4276
4277 buf.index = i;
4278 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4279 buf.memory = V4L2_MEMORY_USERPTR;
4280 plane[0].length = drv_ctx.op_buf.buffer_size;
4281 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4282 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4283 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4284 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4285 plane[0].data_offset = 0;
4286 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4287 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4288 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4289 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4290#ifdef USE_ION
4291 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4292#endif
4293 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4294 plane[extra_idx].data_offset = 0;
4295 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004296 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004297 return OMX_ErrorBadParameter;
4298 }
Arun Menon906de572013-06-18 17:01:40 -07004299 buf.m.planes = plane;
4300 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004301
Arun Menon906de572013-06-18 17:01:40 -07004302 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004303 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004304 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004305 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004306 }
4307
Arun Menon906de572013-06-18 17:01:40 -07004308 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4309 enum v4l2_buf_type buf_type;
4310 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4311 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4312 return OMX_ErrorInsufficientResources;
4313 } else {
4314 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004315 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004316 }
4317 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004318
Arun Menon906de572013-06-18 17:01:40 -07004319 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4320 if (m_enable_android_native_buffers) {
4321 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4322 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4323 } else {
4324 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004325 }
Arun Menon906de572013-06-18 17:01:40 -07004326 (*bufferHdr)->pAppPrivate = privateAppData;
4327 BITMASK_SET(&m_out_bm_count,i);
4328 }
4329 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004330}
4331
4332/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004333 FUNCTION
4334 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004335
Arun Menon906de572013-06-18 17:01:40 -07004336 DESCRIPTION
4337 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004338
Arun Menon906de572013-06-18 17:01:40 -07004339 PARAMETERS
4340 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004341
Arun Menon906de572013-06-18 17:01:40 -07004342 RETURN VALUE
4343 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004344
Arun Menon906de572013-06-18 17:01:40 -07004345 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004346OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004347 OMX_IN OMX_HANDLETYPE hComp,
4348 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4349 OMX_IN OMX_U32 port,
4350 OMX_IN OMX_PTR appData,
4351 OMX_IN OMX_U32 bytes,
4352 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004353{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004354 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004355 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4356 if (!m_inp_heap_ptr)
4357 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4358 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4359 drv_ctx.ip_buf.actualcount);
4360 if (!m_phdr_pmem_ptr)
4361 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4362 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4363 drv_ctx.ip_buf.actualcount);
4364 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4365 DEBUG_PRINT_ERROR("Insufficent memory");
4366 eRet = OMX_ErrorInsufficientResources;
4367 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4368 input_use_buffer = true;
4369 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4370 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4371 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4372 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4373 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4374 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4375 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4376 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004377 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 -07004378 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4379 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004380 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004381 return OMX_ErrorInsufficientResources;
4382 }
4383 m_in_alloc_cnt++;
4384 } else {
4385 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4386 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004387 }
Arun Menon906de572013-06-18 17:01:40 -07004388 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004389}
4390
4391/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004392 FUNCTION
4393 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004394
Arun Menon906de572013-06-18 17:01:40 -07004395 DESCRIPTION
4396 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004397
Arun Menon906de572013-06-18 17:01:40 -07004398 PARAMETERS
4399 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004400
Arun Menon906de572013-06-18 17:01:40 -07004401 RETURN VALUE
4402 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004403
Arun Menon906de572013-06-18 17:01:40 -07004404 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004405OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004406 OMX_IN OMX_HANDLETYPE hComp,
4407 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4408 OMX_IN OMX_U32 port,
4409 OMX_IN OMX_PTR appData,
4410 OMX_IN OMX_U32 bytes,
4411 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004412{
Arun Menon906de572013-06-18 17:01:40 -07004413 OMX_ERRORTYPE error = OMX_ErrorNone;
4414 struct vdec_setbuffer_cmd setbuffers;
4415
4416 if (bufferHdr == NULL || bytes == 0) {
4417 if (!secure_mode && buffer == NULL) {
4418 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4419 return OMX_ErrorBadParameter;
4420 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004421 }
Arun Menon906de572013-06-18 17:01:40 -07004422 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004423 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004424 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004425 }
Arun Menon906de572013-06-18 17:01:40 -07004426 if (port == OMX_CORE_INPUT_PORT_INDEX)
4427 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4428 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4429 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4430 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004431 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004432 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004433 }
Arun Menon906de572013-06-18 17:01:40 -07004434 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4435 if (error == OMX_ErrorNone) {
4436 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4437 // Send the callback now
4438 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4439 post_event(OMX_CommandStateSet,OMX_StateIdle,
4440 OMX_COMPONENT_GENERATE_EVENT);
4441 }
4442 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4443 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4444 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4445 post_event(OMX_CommandPortEnable,
4446 OMX_CORE_INPUT_PORT_INDEX,
4447 OMX_COMPONENT_GENERATE_EVENT);
4448 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4449 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4450 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4451 post_event(OMX_CommandPortEnable,
4452 OMX_CORE_OUTPUT_PORT_INDEX,
4453 OMX_COMPONENT_GENERATE_EVENT);
4454 }
4455 }
4456 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004457}
4458
4459OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004460 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004461{
Arun Menon906de572013-06-18 17:01:40 -07004462 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4463 if (m_inp_heap_ptr[bufferindex].pBuffer)
4464 free(m_inp_heap_ptr[bufferindex].pBuffer);
4465 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4466 }
4467 if (pmem_bufferHdr)
4468 free_input_buffer(pmem_bufferHdr);
4469 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004470}
4471
4472OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4473{
Arun Menon906de572013-06-18 17:01:40 -07004474 unsigned int index = 0;
4475 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4476 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004477 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004478
Arun Menon906de572013-06-18 17:01:40 -07004479 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004480 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004481
4482 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004483 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004484 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4485 struct vdec_setbuffer_cmd setbuffers;
4486 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4487 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4488 sizeof (vdec_bufferpayload));
4489 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004490 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004491 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004492 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004493 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4494 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4495 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4496 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4497 }
4498 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4499 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4500 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4501 free(m_desc_buffer_ptr[index].buf_addr);
4502 m_desc_buffer_ptr[index].buf_addr = NULL;
4503 m_desc_buffer_ptr[index].desc_data_size = 0;
4504 }
4505#ifdef USE_ION
4506 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4507#endif
4508 }
4509 }
4510
4511 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004512}
4513
4514OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4515{
Arun Menon906de572013-06-18 17:01:40 -07004516 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004517
Arun Menon906de572013-06-18 17:01:40 -07004518 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4519 return OMX_ErrorBadParameter;
4520 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004521
Arun Menon906de572013-06-18 17:01:40 -07004522 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004523 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004524
Arun Menon906de572013-06-18 17:01:40 -07004525 if (index < drv_ctx.op_buf.actualcount
4526 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004527 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004528 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004529
Arun Menon906de572013-06-18 17:01:40 -07004530 struct vdec_setbuffer_cmd setbuffers;
4531 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4532 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4533 sizeof (vdec_bufferpayload));
Praveen Chavan61e5d162013-11-01 02:49:19 -07004534
4535 if (!dynamic_buf_mode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004536#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004537 if (m_enable_android_native_buffers) {
Arun Menon906de572013-06-18 17:01:40 -07004538 if (!secure_mode) {
Praveen Chavan61e5d162013-11-01 02:49:19 -07004539 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4540 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4541 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4542 }
Arun Menon906de572013-06-18 17:01:40 -07004543 }
Praveen Chavan61e5d162013-11-01 02:49:19 -07004544 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4545 } else {
4546#endif
4547 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4548 if (!secure_mode) {
4549 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4550 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4551 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4552 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4553 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4554 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4555 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4556 }
4557 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4558 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004559#ifdef USE_ION
Praveen Chavan61e5d162013-11-01 02:49:19 -07004560 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004561#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004562 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004563#ifdef _ANDROID_
Praveen Chavan61e5d162013-11-01 02:49:19 -07004564 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004565#endif
Praveen Chavan61e5d162013-11-01 02:49:19 -07004566 } //!dynamic_buf_mode
Arun Menon906de572013-06-18 17:01:40 -07004567 if (release_output_done()) {
4568 free_extradata();
4569 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004570 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004571
Arun Menon906de572013-06-18 17:01:40 -07004572 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004573
4574}
4575
4576OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004577 OMX_BUFFERHEADERTYPE **bufferHdr,
4578 OMX_U32 port,
4579 OMX_PTR appData,
4580 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004581{
Arun Menon906de572013-06-18 17:01:40 -07004582 OMX_BUFFERHEADERTYPE *input = NULL;
4583 unsigned char *buf_addr = NULL;
4584 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4585 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004586
Arun Menon906de572013-06-18 17:01:40 -07004587 /* Sanity Check*/
4588 if (bufferHdr == NULL) {
4589 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004590 }
4591
Arun Menon906de572013-06-18 17:01:40 -07004592 if (m_inp_heap_ptr == NULL) {
4593 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4594 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4595 drv_ctx.ip_buf.actualcount);
4596 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4597 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4598 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004599
Arun Menon906de572013-06-18 17:01:40 -07004600 if (m_inp_heap_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004601 DEBUG_PRINT_ERROR("m_inp_heap_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004602 return OMX_ErrorInsufficientResources;
4603 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004604 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004605
Arun Menon906de572013-06-18 17:01:40 -07004606 /*Find a Free index*/
4607 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4608 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004609 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004610 break;
4611 }
4612 }
4613
4614 if (i < drv_ctx.ip_buf.actualcount) {
4615 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4616
4617 if (buf_addr == NULL) {
4618 return OMX_ErrorInsufficientResources;
4619 }
4620
4621 *bufferHdr = (m_inp_heap_ptr + i);
4622 input = *bufferHdr;
4623 BITMASK_SET(&m_heap_inp_bm_count,i);
4624
4625 input->pBuffer = (OMX_U8 *)buf_addr;
4626 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4627 input->nVersion.nVersion = OMX_SPEC_VERSION;
4628 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4629 input->pAppPrivate = appData;
4630 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004631 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004632 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004633 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004634 /*Add the Buffers to freeq*/
4635 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4636 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004637 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004638 return OMX_ErrorInsufficientResources;
4639 }
4640 } else {
4641 return OMX_ErrorBadParameter;
4642 }
4643
4644 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004645
4646}
4647
4648
4649/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004650 FUNCTION
4651 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004652
Arun Menon906de572013-06-18 17:01:40 -07004653 DESCRIPTION
4654 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004655
Arun Menon906de572013-06-18 17:01:40 -07004656 PARAMETERS
4657 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004658
Arun Menon906de572013-06-18 17:01:40 -07004659 RETURN VALUE
4660 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004661
Arun Menon906de572013-06-18 17:01:40 -07004662 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004663OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004664 OMX_IN OMX_HANDLETYPE hComp,
4665 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4666 OMX_IN OMX_U32 port,
4667 OMX_IN OMX_PTR appData,
4668 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004669{
4670
Arun Menon906de572013-06-18 17:01:40 -07004671 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4672 struct vdec_setbuffer_cmd setbuffers;
4673 OMX_BUFFERHEADERTYPE *input = NULL;
4674 unsigned i = 0;
4675 unsigned char *buf_addr = NULL;
4676 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004677
Arun Menon906de572013-06-18 17:01:40 -07004678 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004679 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004680 bytes, drv_ctx.ip_buf.buffer_size);
4681 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004682 }
4683
Arun Menon906de572013-06-18 17:01:40 -07004684 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004685 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004686 drv_ctx.ip_buf.actualcount,
4687 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004688
Arun Menon906de572013-06-18 17:01:40 -07004689 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4690 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4691
4692 if (m_inp_mem_ptr == NULL) {
4693 return OMX_ErrorInsufficientResources;
4694 }
4695
4696 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4697 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4698
4699 if (drv_ctx.ptr_inputbuffer == NULL) {
4700 return OMX_ErrorInsufficientResources;
4701 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004702#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004703 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4704 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004705
Arun Menon906de572013-06-18 17:01:40 -07004706 if (drv_ctx.ip_buf_ion_info == NULL) {
4707 return OMX_ErrorInsufficientResources;
4708 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004709#endif
4710
Arun Menon906de572013-06-18 17:01:40 -07004711 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4712 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004713#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004714 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004715#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004716 }
4717 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004718
Arun Menon906de572013-06-18 17:01:40 -07004719 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4720 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004721 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004722 break;
4723 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004724 }
Arun Menon906de572013-06-18 17:01:40 -07004725
4726 if (i < drv_ctx.ip_buf.actualcount) {
4727 struct v4l2_buffer buf;
4728 struct v4l2_plane plane;
4729 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004730 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004731#ifdef USE_ION
4732 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4733 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4734 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4735 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4736 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4737 return OMX_ErrorInsufficientResources;
4738 }
4739 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4740#else
4741 pmem_fd = open (MEM_DEVICE,O_RDWR);
4742
4743 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004744 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004745 return OMX_ErrorInsufficientResources;
4746 }
4747
4748 if (pmem_fd == 0) {
4749 pmem_fd = open (MEM_DEVICE,O_RDWR);
4750
4751 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004752 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004753 return OMX_ErrorInsufficientResources;
4754 }
4755 }
4756
4757 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4758 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004759 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004760 close(pmem_fd);
4761 return OMX_ErrorInsufficientResources;
4762 }
4763#endif
4764 if (!secure_mode) {
4765 buf_addr = (unsigned char *)mmap(NULL,
4766 drv_ctx.ip_buf.buffer_size,
4767 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4768
4769 if (buf_addr == MAP_FAILED) {
4770 close(pmem_fd);
4771#ifdef USE_ION
4772 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4773#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004774 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004775 return OMX_ErrorInsufficientResources;
4776 }
4777 }
4778 *bufferHdr = (m_inp_mem_ptr + i);
4779 if (secure_mode)
4780 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4781 else
4782 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4783 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4784 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4785 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4786 drv_ctx.ptr_inputbuffer [i].offset = 0;
4787
4788
4789 buf.index = i;
4790 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4791 buf.memory = V4L2_MEMORY_USERPTR;
4792 plane.bytesused = 0;
4793 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4794 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4795 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4796 plane.reserved[1] = 0;
4797 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4798 buf.m.planes = &plane;
4799 buf.length = 1;
4800
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004801 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07004802 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4803
4804 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4805
4806 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004807 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004808 /*TODO: How to handle this case */
4809 return OMX_ErrorInsufficientResources;
4810 }
4811
4812 input = *bufferHdr;
4813 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004814 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07004815 if (secure_mode)
4816 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4817 else
4818 input->pBuffer = (OMX_U8 *)buf_addr;
4819 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4820 input->nVersion.nVersion = OMX_SPEC_VERSION;
4821 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4822 input->pAppPrivate = appData;
4823 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4824 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4825
4826 if (drv_ctx.disable_dmx) {
4827 eRet = allocate_desc_buffer(i);
4828 }
4829 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004830 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07004831 eRet = OMX_ErrorInsufficientResources;
4832 }
4833 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004834}
4835
4836
4837/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004838 FUNCTION
4839 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004840
Arun Menon906de572013-06-18 17:01:40 -07004841 DESCRIPTION
4842 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004843
Arun Menon906de572013-06-18 17:01:40 -07004844 PARAMETERS
4845 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004846
Arun Menon906de572013-06-18 17:01:40 -07004847 RETURN VALUE
4848 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004849
Arun Menon906de572013-06-18 17:01:40 -07004850 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004851OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004852 OMX_IN OMX_HANDLETYPE hComp,
4853 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4854 OMX_IN OMX_U32 port,
4855 OMX_IN OMX_PTR appData,
4856 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004857{
Arun Menon906de572013-06-18 17:01:40 -07004858 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4859 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4860 unsigned i= 0; // Temporary counter
4861 struct vdec_setbuffer_cmd setbuffers;
4862 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004863#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004864 int ion_device_fd =-1;
4865 struct ion_allocation_data ion_alloc_data;
4866 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004867#endif
Arun Menon906de572013-06-18 17:01:40 -07004868 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004869 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004870 drv_ctx.op_buf.actualcount,
4871 drv_ctx.op_buf.buffer_size);
4872 int nBufHdrSize = 0;
4873 int nPlatformEntrySize = 0;
4874 int nPlatformListSize = 0;
4875 int nPMEMInfoSize = 0;
4876 int pmem_fd = -1;
4877 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004878
Arun Menon906de572013-06-18 17:01:40 -07004879 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4880 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4881 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004882
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004883 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004884 drv_ctx.op_buf.actualcount);
4885 nBufHdrSize = drv_ctx.op_buf.actualcount *
4886 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004887
Arun Menon906de572013-06-18 17:01:40 -07004888 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4889 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4890 nPlatformListSize = drv_ctx.op_buf.actualcount *
4891 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4892 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4893 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004894
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004895 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07004896 sizeof(OMX_BUFFERHEADERTYPE),
4897 nPMEMInfoSize,
4898 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004899 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07004900 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004901#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004902 ion_device_fd = alloc_map_ion_memory(
4903 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4904 drv_ctx.op_buf.alignment,
4905 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4906 if (ion_device_fd < 0) {
4907 return OMX_ErrorInsufficientResources;
4908 }
4909 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004910#else
Arun Menon906de572013-06-18 17:01:40 -07004911 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004912
Arun Menon906de572013-06-18 17:01:40 -07004913 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004914 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004915 drv_ctx.op_buf.buffer_size);
4916 return OMX_ErrorInsufficientResources;
4917 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004918
Arun Menon906de572013-06-18 17:01:40 -07004919 if (pmem_fd == 0) {
4920 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004921
Arun Menon906de572013-06-18 17:01:40 -07004922 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004923 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004924 drv_ctx.op_buf.buffer_size);
4925 return OMX_ErrorInsufficientResources;
4926 }
4927 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004928
Arun Menon906de572013-06-18 17:01:40 -07004929 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4930 drv_ctx.op_buf.actualcount,
4931 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004932 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004933 close(pmem_fd);
4934 return OMX_ErrorInsufficientResources;
4935 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004936#endif
Arun Menon906de572013-06-18 17:01:40 -07004937 if (!secure_mode) {
4938 pmem_baseaddress = (unsigned char *)mmap(NULL,
4939 (drv_ctx.op_buf.buffer_size *
4940 drv_ctx.op_buf.actualcount),
4941 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4942 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004943 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07004944 drv_ctx.op_buf.buffer_size);
4945 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004946#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004947 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004948#endif
Arun Menon906de572013-06-18 17:01:40 -07004949 return OMX_ErrorInsufficientResources;
4950 }
4951 }
4952 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4953 // Alloc mem for platform specific info
4954 char *pPtr=NULL;
4955 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4956 nPMEMInfoSize,1);
4957 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4958 calloc (sizeof(struct vdec_bufferpayload),
4959 drv_ctx.op_buf.actualcount);
4960 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4961 calloc (sizeof (struct vdec_output_frameinfo),
4962 drv_ctx.op_buf.actualcount);
4963#ifdef USE_ION
4964 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4965 calloc (sizeof(struct vdec_ion),
4966 drv_ctx.op_buf.actualcount);
4967#endif
4968
4969 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4970 && drv_ctx.ptr_respbuffer) {
4971 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4972 (drv_ctx.op_buf.buffer_size *
4973 drv_ctx.op_buf.actualcount);
4974 bufHdr = m_out_mem_ptr;
4975 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4976 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4977 (((char *) m_platform_list) + nPlatformListSize);
4978 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4979 (((char *) m_platform_entry) + nPlatformEntrySize);
4980 pPlatformList = m_platform_list;
4981 pPlatformEntry = m_platform_entry;
4982 pPMEMInfo = m_pmem_info;
4983
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004984 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07004985
4986 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004987 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
4988 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07004989 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4990 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4991 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4992 // Set the values when we determine the right HxW param
4993 bufHdr->nAllocLen = bytes;
4994 bufHdr->nFilledLen = 0;
4995 bufHdr->pAppPrivate = appData;
4996 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4997 // Platform specific PMEM Information
4998 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004999 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005000 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5001 pPlatformEntry->entry = pPMEMInfo;
5002 // Initialize the Platform List
5003 pPlatformList->nEntries = 1;
5004 pPlatformList->entryList = pPlatformEntry;
5005 // Keep pBuffer NULL till vdec is opened
5006 bufHdr->pBuffer = NULL;
5007 bufHdr->nOffset = 0;
5008
5009 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5010 pPMEMInfo->pmem_fd = 0;
5011 bufHdr->pPlatformPrivate = pPlatformList;
5012
5013 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
5014 m_pmem_info[i].pmem_fd = pmem_fd;
5015#ifdef USE_ION
5016 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5017 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5018 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5019#endif
5020
5021 /*Create a mapping between buffers*/
5022 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5023 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5024 &drv_ctx.ptr_outputbuffer[i];
5025 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5026 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5027 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305028 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5029 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5030 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005031
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005032 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005033 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5034 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5035 // Move the buffer and buffer header pointers
5036 bufHdr++;
5037 pPMEMInfo++;
5038 pPlatformEntry++;
5039 pPlatformList++;
5040 }
5041 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005042 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005043 m_out_mem_ptr, pPtr);
5044 if (m_out_mem_ptr) {
5045 free(m_out_mem_ptr);
5046 m_out_mem_ptr = NULL;
5047 }
5048 if (pPtr) {
5049 free(pPtr);
5050 pPtr = NULL;
5051 }
5052 if (drv_ctx.ptr_outputbuffer) {
5053 free(drv_ctx.ptr_outputbuffer);
5054 drv_ctx.ptr_outputbuffer = NULL;
5055 }
5056 if (drv_ctx.ptr_respbuffer) {
5057 free(drv_ctx.ptr_respbuffer);
5058 drv_ctx.ptr_respbuffer = NULL;
5059 }
5060#ifdef USE_ION
5061 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005062 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005063 free(drv_ctx.op_buf_ion_info);
5064 drv_ctx.op_buf_ion_info = NULL;
5065 }
5066#endif
5067 eRet = OMX_ErrorInsufficientResources;
5068 }
5069 if (eRet == OMX_ErrorNone)
5070 eRet = allocate_extradata();
5071 }
5072
5073 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5074 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005075 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005076 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005077 }
5078 }
Arun Menon906de572013-06-18 17:01:40 -07005079
5080 if (eRet == OMX_ErrorNone) {
5081 if (i < drv_ctx.op_buf.actualcount) {
5082 struct v4l2_buffer buf;
5083 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5084 int rc;
5085 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5086
5087 drv_ctx.ptr_outputbuffer[i].buffer_len =
5088 drv_ctx.op_buf.buffer_size;
5089
5090 *bufferHdr = (m_out_mem_ptr + i );
5091 if (secure_mode) {
5092 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5093 }
5094 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5095
5096 buf.index = i;
5097 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5098 buf.memory = V4L2_MEMORY_USERPTR;
5099 plane[0].length = drv_ctx.op_buf.buffer_size;
5100 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5101 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005102#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005103 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005104#endif
Arun Menon906de572013-06-18 17:01:40 -07005105 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5106 plane[0].data_offset = 0;
5107 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5108 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5109 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5110 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 -07005111#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005112 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005113#endif
Arun Menon906de572013-06-18 17:01:40 -07005114 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5115 plane[extra_idx].data_offset = 0;
5116 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005117 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005118 return OMX_ErrorBadParameter;
5119 }
5120 buf.m.planes = plane;
5121 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005122 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 -07005123 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5124 if (rc) {
5125 /*TODO: How to handle this case */
5126 return OMX_ErrorInsufficientResources;
5127 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005128
Arun Menon906de572013-06-18 17:01:40 -07005129 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5130 enum v4l2_buf_type buf_type;
5131 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5132 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5133 if (rc) {
5134 return OMX_ErrorInsufficientResources;
5135 } else {
5136 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005137 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005138 }
5139 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005140
Arun Menon906de572013-06-18 17:01:40 -07005141 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5142 (*bufferHdr)->pAppPrivate = appData;
5143 BITMASK_SET(&m_out_bm_count,i);
5144 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005145 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005146 eRet = OMX_ErrorInsufficientResources;
5147 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005148 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005149
Arun Menon906de572013-06-18 17:01:40 -07005150 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005151}
5152
5153
5154// AllocateBuffer -- API Call
5155/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005156 FUNCTION
5157 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005158
Arun Menon906de572013-06-18 17:01:40 -07005159 DESCRIPTION
5160 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005161
Arun Menon906de572013-06-18 17:01:40 -07005162 PARAMETERS
5163 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005164
Arun Menon906de572013-06-18 17:01:40 -07005165 RETURN VALUE
5166 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005167
Arun Menon906de572013-06-18 17:01:40 -07005168 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005169OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005170 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5171 OMX_IN OMX_U32 port,
5172 OMX_IN OMX_PTR appData,
5173 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005174{
5175 unsigned i = 0;
5176 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5177
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005178 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005179 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005180 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005181 return OMX_ErrorInvalidState;
5182 }
5183
Arun Menon906de572013-06-18 17:01:40 -07005184 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5185 if (arbitrary_bytes) {
5186 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5187 } else {
5188 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5189 }
5190 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005191 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5192 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005193 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005194 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005195 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005196 }
5197 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005198 if (eRet == OMX_ErrorNone) {
5199 if (allocate_done()) {
5200 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005201 // Send the callback now
5202 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5203 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005204 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005205 }
5206 }
Arun Menon906de572013-06-18 17:01:40 -07005207 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5208 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5209 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5210 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005211 OMX_CORE_INPUT_PORT_INDEX,
5212 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005213 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005214 }
Arun Menon906de572013-06-18 17:01:40 -07005215 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5216 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5217 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005218 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005219 OMX_CORE_OUTPUT_PORT_INDEX,
5220 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005221 }
5222 }
5223 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005224 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005225 return eRet;
5226}
5227
5228// Free Buffer - API call
5229/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005230 FUNCTION
5231 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005232
Arun Menon906de572013-06-18 17:01:40 -07005233 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005234
Arun Menon906de572013-06-18 17:01:40 -07005235 PARAMETERS
5236 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005237
Arun Menon906de572013-06-18 17:01:40 -07005238 RETURN VALUE
5239 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005240
Arun Menon906de572013-06-18 17:01:40 -07005241 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005242OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005243 OMX_IN OMX_U32 port,
5244 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005245{
5246 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5247 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005248 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005249
Arun Menon906de572013-06-18 17:01:40 -07005250 if (m_state == OMX_StateIdle &&
5251 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005252 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005253 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5254 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005255 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005256 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5257 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5258 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5259 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005260 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005261 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005262 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005263 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005264 OMX_ErrorPortUnpopulated,
5265 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005266
5267 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005268 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005269 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005270 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005271 OMX_ErrorPortUnpopulated,
5272 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005273 }
5274
Arun Menon906de572013-06-18 17:01:40 -07005275 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5276 /*Check if arbitrary bytes*/
5277 if (!arbitrary_bytes && !input_use_buffer)
5278 nPortIndex = buffer - m_inp_mem_ptr;
5279 else
5280 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005281
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005282 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005283 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5284 // Clear the bit associated with it.
5285 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5286 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5287 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005288
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005289 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005290 if (m_phdr_pmem_ptr)
5291 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5292 } else {
5293 if (arbitrary_bytes) {
5294 if (m_phdr_pmem_ptr)
5295 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5296 else
5297 free_input_buffer(nPortIndex,NULL);
5298 } else
5299 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005300 }
Arun Menon906de572013-06-18 17:01:40 -07005301 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305302 if(release_input_done())
5303 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005304 /*Free the Buffer Header*/
5305 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005306 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005307 free_input_buffer_header();
5308 }
5309 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005310 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005311 eRet = OMX_ErrorBadPortIndex;
5312 }
5313
Arun Menon906de572013-06-18 17:01:40 -07005314 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5315 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005316 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005317 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5318 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005319 OMX_CORE_INPUT_PORT_INDEX,
5320 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005321 }
Arun Menon906de572013-06-18 17:01:40 -07005322 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005323 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005324 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005325 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005326 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005327 // Clear the bit associated with it.
5328 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5329 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005330 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005331
Surajit Podder12aefac2013-08-06 18:43:32 +05305332 if(release_output_done()) {
5333 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5334 }
Arun Menon906de572013-06-18 17:01:40 -07005335 if (release_output_done()) {
5336 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005337 }
Arun Menon906de572013-06-18 17:01:40 -07005338 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005339 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005340 eRet = OMX_ErrorBadPortIndex;
5341 }
Arun Menon906de572013-06-18 17:01:40 -07005342 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5343 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005344 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005345
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005346 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005347 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005348#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005349 if (m_enable_android_native_buffers) {
5350 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5351 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5352 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005353#endif
5354
Arun Menon906de572013-06-18 17:01:40 -07005355 post_event(OMX_CommandPortDisable,
5356 OMX_CORE_OUTPUT_PORT_INDEX,
5357 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005358 }
Arun Menon906de572013-06-18 17:01:40 -07005359 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005360 eRet = OMX_ErrorBadPortIndex;
5361 }
Arun Menon906de572013-06-18 17:01:40 -07005362 if ((eRet == OMX_ErrorNone) &&
5363 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5364 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005365 // Send the callback now
5366 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5367 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005368 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005369 }
5370 }
5371 return eRet;
5372}
5373
5374
5375/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005376 FUNCTION
5377 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005378
Arun Menon906de572013-06-18 17:01:40 -07005379 DESCRIPTION
5380 This routine is used to push the encoded video frames to
5381 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005382
Arun Menon906de572013-06-18 17:01:40 -07005383 PARAMETERS
5384 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005385
Arun Menon906de572013-06-18 17:01:40 -07005386 RETURN VALUE
5387 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005388
Arun Menon906de572013-06-18 17:01:40 -07005389 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005390OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005391 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005392{
Arun Menon906de572013-06-18 17:01:40 -07005393 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5394 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005395
Arun Menon906de572013-06-18 17:01:40 -07005396 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005397 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005398 return OMX_ErrorInvalidState;
5399 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005400
Arun Menon906de572013-06-18 17:01:40 -07005401 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005402 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005403 return OMX_ErrorBadParameter;
5404 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005405
Arun Menon906de572013-06-18 17:01:40 -07005406 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005407 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005408 return OMX_ErrorIncorrectStateOperation;
5409 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005410
Arun Menon906de572013-06-18 17:01:40 -07005411 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005412 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005413 return OMX_ErrorBadPortIndex;
5414 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005415
5416#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005417 if (iDivXDrmDecrypt) {
5418 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5419 if (drmErr != OMX_ErrorNone) {
5420 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005421 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005422 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005423 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005424#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005425 if (perf_flag) {
5426 if (!latency) {
5427 dec_time.stop();
5428 latency = dec_time.processing_time_us();
5429 dec_time.start();
5430 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005431 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005432
Arun Menon906de572013-06-18 17:01:40 -07005433 if (arbitrary_bytes) {
5434 nBufferIndex = buffer - m_inp_heap_ptr;
5435 } else {
5436 if (input_use_buffer == true) {
5437 nBufferIndex = buffer - m_inp_heap_ptr;
5438 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5439 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5440 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5441 buffer = &m_inp_mem_ptr[nBufferIndex];
5442 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5443 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5444 } else {
5445 nBufferIndex = buffer - m_inp_mem_ptr;
5446 }
5447 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005448
Arun Menon906de572013-06-18 17:01:40 -07005449 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005450 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005451 return OMX_ErrorBadParameter;
5452 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005453
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005454 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5455 codec_config_flag = true;
5456 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5457 }
5458
Arun Menon906de572013-06-18 17:01:40 -07005459 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5460 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5461 if (arbitrary_bytes) {
5462 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005463 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005464 } else {
Arun Menon906de572013-06-18 17:01:40 -07005465 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5466 }
5467 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005468}
5469
5470/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005471 FUNCTION
5472 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005473
Arun Menon906de572013-06-18 17:01:40 -07005474 DESCRIPTION
5475 This routine is used to push the encoded video frames to
5476 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005477
Arun Menon906de572013-06-18 17:01:40 -07005478 PARAMETERS
5479 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005480
Arun Menon906de572013-06-18 17:01:40 -07005481 RETURN VALUE
5482 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005483
Arun Menon906de572013-06-18 17:01:40 -07005484 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005485OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005486 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005487{
Arun Menon906de572013-06-18 17:01:40 -07005488 int push_cnt = 0,i=0;
5489 unsigned nPortIndex = 0;
5490 OMX_ERRORTYPE ret = OMX_ErrorNone;
5491 struct vdec_input_frameinfo frameinfo;
5492 struct vdec_bufferpayload *temp_buffer;
5493 struct vdec_seqheader seq_header;
5494 bool port_setting_changed = true;
5495 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005496
Arun Menon906de572013-06-18 17:01:40 -07005497 /*Should we generate a Aync error event*/
5498 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005499 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005500 return OMX_ErrorBadParameter;
5501 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005502
Arun Menon906de572013-06-18 17:01:40 -07005503 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005504
Arun Menon906de572013-06-18 17:01:40 -07005505 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005506 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005507 nPortIndex);
5508 return OMX_ErrorBadParameter;
5509 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005510
Arun Menon906de572013-06-18 17:01:40 -07005511 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005512
Arun Menon906de572013-06-18 17:01:40 -07005513 /* return zero length and not an EOS buffer */
5514 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5515 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005516 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005517 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5518 OMX_COMPONENT_GENERATE_EBD);
5519 return OMX_ErrorNone;
5520 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005521
5522
Arun Menon906de572013-06-18 17:01:40 -07005523 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5524 mp4StreamType psBits;
5525 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5526 psBits.numBytes = buffer->nFilledLen;
5527 mp4_headerparser.parseHeader(&psBits);
5528 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5529 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5530 if (not_coded_vop) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005531 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u",
Arun Menon906de572013-06-18 17:01:40 -07005532 buffer->nFilledLen,frame_count);
5533 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005534 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
Arun Menon906de572013-06-18 17:01:40 -07005535 not_coded_vop = false;
5536 buffer->nFilledLen = 0;
5537 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005538 }
5539 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005540
Arun Menon906de572013-06-18 17:01:40 -07005541 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005542
Arun Menon906de572013-06-18 17:01:40 -07005543 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005544
Arun Menon906de572013-06-18 17:01:40 -07005545 ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005546 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005547 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5548 OMX_COMPONENT_GENERATE_EBD);
5549 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005550 }
5551
Arun Menon906de572013-06-18 17:01:40 -07005552 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005553
Surajit Podderd2644d52013-08-28 17:59:06 +05305554 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005555 return OMX_ErrorBadParameter;
5556 }
5557 /* If its first frame, H264 codec and reject is true, then parse the nal
5558 and get the profile. Based on this, reject the clip playback */
5559 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5560 m_reject_avc_1080p_mp) {
5561 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005562 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005563 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5564 NALU_TYPE_SPS);
5565 m_profile = h264_parser->get_profile();
5566 ret = is_video_session_supported();
5567 if (ret) {
5568 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5569 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5570 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5571 m_state = OMX_StateInvalid;
5572 return OMX_ErrorNone;
5573 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005574 }
5575
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005576 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005577 /*for use buffer we need to memcpy the data*/
5578 temp_buffer->buffer_len = buffer->nFilledLen;
5579
5580 if (input_use_buffer) {
5581 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5582 if (arbitrary_bytes) {
5583 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5584 } else {
5585 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5586 buffer->nFilledLen);
5587 }
5588 } else {
5589 return OMX_ErrorBadParameter;
5590 }
5591
5592 }
5593
Vikash Garodia3c47b182013-12-20 18:38:17 +05305594 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5595 set_frame_rate(buffer->nTimeStamp);
5596
Arun Menon906de572013-06-18 17:01:40 -07005597 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5598 frameinfo.client_data = (void *) buffer;
5599 frameinfo.datalen = temp_buffer->buffer_len;
5600 frameinfo.flags = 0;
5601 frameinfo.offset = buffer->nOffset;
5602 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5603 frameinfo.pmem_offset = temp_buffer->offset;
5604 frameinfo.timestamp = buffer->nTimeStamp;
5605 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5606 DEBUG_PRINT_LOW("ETB: dmx enabled");
5607 if (m_demux_entries == 0) {
5608 extract_demux_addr_offsets(buffer);
5609 }
5610
5611 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5612 handle_demux_data(buffer);
5613 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5614 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5615 } else {
5616 frameinfo.desc_addr = NULL;
5617 frameinfo.desc_size = 0;
5618 }
5619 if (!arbitrary_bytes) {
5620 frameinfo.flags |= buffer->nFlags;
5621 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005622
5623#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005624 if (m_debug_timestamp) {
5625 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005626 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005627 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5628 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005629 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005630 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5631 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005632 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005633#endif
5634
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005635log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005636
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005637if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005638 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5639 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5640 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005641
Arun Menon906de572013-06-18 17:01:40 -07005642 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005643 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005644 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5645 h264_scratch.nFilledLen = 0;
5646 nal_count = 0;
5647 look_ahead_nal = false;
5648 frame_count = 0;
5649 if (m_frame_parser.mutils)
5650 m_frame_parser.mutils->initialize_frame_checking_environment();
5651 m_frame_parser.flush();
5652 h264_last_au_ts = LLONG_MAX;
5653 h264_last_au_flags = 0;
5654 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5655 m_demux_entries = 0;
5656 }
5657 struct v4l2_buffer buf;
5658 struct v4l2_plane plane;
5659 memset( (void *)&buf, 0, sizeof(buf));
5660 memset( (void *)&plane, 0, sizeof(plane));
5661 int rc;
5662 unsigned long print_count;
5663 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005664 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005665 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005666 }
5667 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5668 buf.index = nPortIndex;
5669 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5670 buf.memory = V4L2_MEMORY_USERPTR;
5671 plane.bytesused = temp_buffer->buffer_len;
5672 plane.length = drv_ctx.ip_buf.buffer_size;
5673 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5674 (unsigned long)temp_buffer->offset;
5675 plane.reserved[0] = temp_buffer->pmem_fd;
5676 plane.reserved[1] = temp_buffer->offset;
5677 plane.data_offset = 0;
5678 buf.m.planes = &plane;
5679 buf.length = 1;
5680 if (frameinfo.timestamp >= LLONG_MAX) {
5681 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5682 }
5683 //assumption is that timestamp is in milliseconds
5684 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5685 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5686 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5687 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005688
Arun Menon906de572013-06-18 17:01:40 -07005689 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5690 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005691 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005692 return OMX_ErrorHardware;
5693 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005694 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5695 codec_config_flag = false;
5696 }
Arun Menon906de572013-06-18 17:01:40 -07005697 if (!streaming[OUTPUT_PORT]) {
5698 enum v4l2_buf_type buf_type;
5699 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005700
Arun Menon906de572013-06-18 17:01:40 -07005701 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005702 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005703 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5704 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005705 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005706 streaming[OUTPUT_PORT] = true;
5707 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005708 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005709 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5710 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5711 OMX_COMPONENT_GENERATE_EBD);
5712 return OMX_ErrorBadParameter;
5713 }
5714 }
5715 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5716 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5717 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005718
Arun Menon906de572013-06-18 17:01:40 -07005719 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005720}
5721
5722/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005723 FUNCTION
5724 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005725
Arun Menon906de572013-06-18 17:01:40 -07005726 DESCRIPTION
5727 IL client uses this method to release the frame buffer
5728 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005729
Arun Menon906de572013-06-18 17:01:40 -07005730 PARAMETERS
5731 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005732
Arun Menon906de572013-06-18 17:01:40 -07005733 RETURN VALUE
5734 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005735
Arun Menon906de572013-06-18 17:01:40 -07005736 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005737OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005738 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005739{
Arun Menonbdb80b02013-08-12 17:45:54 -07005740 if (dynamic_buf_mode) {
5741 private_handle_t *handle = NULL;
5742 struct VideoDecoderOutputMetaData *meta;
Arun Menonbdb80b02013-08-12 17:45:54 -07005743 unsigned int nPortIndex = 0;
5744
5745 if (!buffer || !buffer->pBuffer) {
5746 DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
5747 return OMX_ErrorBadParameter;
5748 }
5749
5750 //get the buffer type and fd info
5751 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5752 handle = (private_handle_t *)meta->pHandle;
Arun Menonb49abf22013-12-14 21:38:10 -08005753 DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
5754
5755 if (!handle) {
5756 DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
5757 return OMX_ErrorBadParameter;
5758 }
Arun Menonbdb80b02013-08-12 17:45:54 -07005759 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5760 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5761 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
Arun Menon50ab1bf2014-01-08 18:02:19 -08005762 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08005763
5764 //Store private handle from GraphicBuffer
5765 native_buffer[nPortIndex].privatehandle = handle;
5766 native_buffer[nPortIndex].nativehandle = handle;
Arun Menonbdb80b02013-08-12 17:45:54 -07005767 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005768
Arun Menon906de572013-06-18 17:01:40 -07005769 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005770 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005771 return OMX_ErrorInvalidState;
5772 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005773
Arun Menon906de572013-06-18 17:01:40 -07005774 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005775 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005776 return OMX_ErrorIncorrectStateOperation;
5777 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005778
Arun Menon906de572013-06-18 17:01:40 -07005779 if (buffer == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05305780 ((buffer - client_buffers.get_il_buf_hdr()) >= (int)drv_ctx.op_buf.actualcount)) {
Arun Menon906de572013-06-18 17:01:40 -07005781 return OMX_ErrorBadParameter;
5782 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005783
Arun Menon906de572013-06-18 17:01:40 -07005784 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005785 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005786 return OMX_ErrorBadPortIndex;
5787 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005788
Arun Menon906de572013-06-18 17:01:40 -07005789 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5790 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5791 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005792}
5793/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005794 FUNCTION
5795 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005796
Arun Menon906de572013-06-18 17:01:40 -07005797 DESCRIPTION
5798 IL client uses this method to release the frame buffer
5799 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005800
Arun Menon906de572013-06-18 17:01:40 -07005801 PARAMETERS
5802 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005803
Arun Menon906de572013-06-18 17:01:40 -07005804 RETURN VALUE
5805 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005806
Arun Menon906de572013-06-18 17:01:40 -07005807 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005808OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005809 OMX_IN OMX_HANDLETYPE hComp,
5810 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005811{
Arun Menon906de572013-06-18 17:01:40 -07005812 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5813 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5814 unsigned nPortIndex = 0;
5815 struct vdec_fillbuffer_cmd fillbuffer;
5816 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5817 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005818
Arun Menon906de572013-06-18 17:01:40 -07005819 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005820
Arun Menon906de572013-06-18 17:01:40 -07005821 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5822 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005823
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005824 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07005825 bufferAdd, bufferAdd->pBuffer);
5826 /*Return back the output buffer to client*/
5827 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005828 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07005829 buffer->nFilledLen = 0;
5830 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5831 return OMX_ErrorNone;
5832 }
Arun Menon50ab1bf2014-01-08 18:02:19 -08005833
5834 if (dynamic_buf_mode) {
5835 //map the buffer handle based on the size set on output port definition.
5836 if (!secure_mode) {
5837 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
5838 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5839 PROT_READ|PROT_WRITE, MAP_SHARED,
5840 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
5841 }
5842 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5843 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5844 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5845 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5846 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5847 }
5848
Arun Menon906de572013-06-18 17:01:40 -07005849 pending_output_buffers++;
5850 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5851 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5852 if (ptr_respbuffer) {
5853 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5854 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005855
Arun Menon906de572013-06-18 17:01:40 -07005856 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5857 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5858 buffer->nFilledLen = 0;
5859 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5860 pending_output_buffers--;
5861 return OMX_ErrorBadParameter;
5862 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005863
Arun Menon906de572013-06-18 17:01:40 -07005864 int rc = 0;
5865 struct v4l2_buffer buf;
5866 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5867 memset( (void *)&buf, 0, sizeof(buf));
5868 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5869 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005870
Arun Menon906de572013-06-18 17:01:40 -07005871 buf.index = nPortIndex;
5872 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5873 buf.memory = V4L2_MEMORY_USERPTR;
5874 plane[0].bytesused = buffer->nFilledLen;
5875 plane[0].length = drv_ctx.op_buf.buffer_size;
5876 plane[0].m.userptr =
5877 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5878 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5879 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5880 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5881 plane[0].data_offset = 0;
5882 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5883 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5884 plane[extra_idx].bytesused = 0;
5885 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5886 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 -07005887#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005888 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005889#endif
Arun Menon906de572013-06-18 17:01:40 -07005890 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5891 plane[extra_idx].data_offset = 0;
5892 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005893 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005894 return OMX_ErrorBadParameter;
5895 }
5896 buf.m.planes = plane;
5897 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005898 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07005899 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5900
Arun Menon906de572013-06-18 17:01:40 -07005901 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5902 if (rc) {
5903 /*TODO: How to handle this case */
5904 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5905 }
Arun Menon906de572013-06-18 17:01:40 -07005906return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005907}
5908
5909/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005910 FUNCTION
5911 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005912
Arun Menon906de572013-06-18 17:01:40 -07005913 DESCRIPTION
5914 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005915
Arun Menon906de572013-06-18 17:01:40 -07005916 PARAMETERS
5917 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005918
Arun Menon906de572013-06-18 17:01:40 -07005919 RETURN VALUE
5920 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005921
Arun Menon906de572013-06-18 17:01:40 -07005922 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005923OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005924 OMX_IN OMX_CALLBACKTYPE* callbacks,
5925 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005926{
5927
Arun Menon906de572013-06-18 17:01:40 -07005928 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005929 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07005930 m_cb.EventHandler,m_cb.FillBufferDone);
5931 m_app_data = appData;
5932 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005933}
5934
5935/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005936 FUNCTION
5937 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005938
Arun Menon906de572013-06-18 17:01:40 -07005939 DESCRIPTION
5940 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005941
Arun Menon906de572013-06-18 17:01:40 -07005942 PARAMETERS
5943 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005944
Arun Menon906de572013-06-18 17:01:40 -07005945 RETURN VALUE
5946 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005947
Arun Menon906de572013-06-18 17:01:40 -07005948 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005949OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5950{
5951#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005952 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005953 delete iDivXDrmDecrypt;
5954 iDivXDrmDecrypt=NULL;
5955 }
5956#endif //_ANDROID_
5957
Shalaj Jain286b0062013-02-21 20:35:48 -08005958 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005959 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005960 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07005961 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005962 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005963 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005964 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005965 }
5966
5967 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005968 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005969 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07005970 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5971 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005972 }
5973#ifdef _ANDROID_ICS_
5974 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5975#endif
5976 }
5977
5978 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005979 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005980 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07005981 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5982 if (m_inp_mem_ptr)
5983 free_input_buffer (i,&m_inp_mem_ptr[i]);
5984 else
5985 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005986 }
5987 }
5988 free_input_buffer_header();
5989 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005990 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005991 free(h264_scratch.pBuffer);
5992 h264_scratch.pBuffer = NULL;
5993 }
5994
Arun Menon906de572013-06-18 17:01:40 -07005995 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005996 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005997 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005998 }
5999
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006000 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006001 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07006002 delete (m_frame_parser.mutils);
6003 m_frame_parser.mutils = NULL;
6004 }
6005
Arun Menon906de572013-06-18 17:01:40 -07006006 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006007 free(m_platform_list);
6008 m_platform_list = NULL;
6009 }
Arun Menon906de572013-06-18 17:01:40 -07006010 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006011 free(m_vendor_config.pData);
6012 m_vendor_config.pData = NULL;
6013 }
6014
6015 // Reset counters in mesg queues
6016 m_ftb_q.m_size=0;
6017 m_cmd_q.m_size=0;
6018 m_etb_q.m_size=0;
6019 m_ftb_q.m_read = m_ftb_q.m_write =0;
6020 m_cmd_q.m_read = m_cmd_q.m_write =0;
6021 m_etb_q.m_read = m_etb_q.m_write =0;
6022#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07006023 if (m_debug_timestamp) {
6024 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006025 }
6026#endif
6027
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006028 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006029 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006030 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006031 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006032
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006033 if (m_debug.infile) {
6034 fclose(m_debug.infile);
6035 m_debug.infile = NULL;
6036 }
6037 if (m_debug.outfile) {
6038 fclose(m_debug.outfile);
6039 m_debug.outfile = NULL;
6040 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006041#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006042 if (outputExtradataFile)
6043 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006044#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006045 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006046 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006047}
6048
6049/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006050 FUNCTION
6051 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006052
Arun Menon906de572013-06-18 17:01:40 -07006053 DESCRIPTION
6054 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006055
Arun Menon906de572013-06-18 17:01:40 -07006056 PARAMETERS
6057 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006058
Arun Menon906de572013-06-18 17:01:40 -07006059 RETURN VALUE
6060 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006061
Arun Menon906de572013-06-18 17:01:40 -07006062 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006063OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006064 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6065 OMX_IN OMX_U32 port,
6066 OMX_IN OMX_PTR appData,
6067 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006068{
Arun Menon906de572013-06-18 17:01:40 -07006069 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6070 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6071 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006072
6073#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006074 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6075 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006076#else
Arun Menon906de572013-06-18 17:01:40 -07006077 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006078#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006079 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006080 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006081 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006082 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006083#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006084 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006085 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006086 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006087 }
6088 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6089 eglGetProcAddress("eglQueryImageKHR");
6090 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6091 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6092 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006093#else //with OMX test app
6094 struct temp_egl {
6095 int pmem_fd;
6096 int offset;
6097 };
6098 struct temp_egl *temp_egl_id = NULL;
6099 void * pmemPtr = (void *) eglImage;
6100 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006101 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006102 fd = temp_egl_id->pmem_fd;
6103 offset = temp_egl_id->offset;
6104 }
6105#endif
6106 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006107 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006108 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006109 }
6110 pmem_info.pmem_fd = (OMX_U32) fd;
6111 pmem_info.offset = (OMX_U32) offset;
6112 pmem_entry.entry = (void *) &pmem_info;
6113 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6114 pmem_list.entryList = &pmem_entry;
6115 pmem_list.nEntries = 1;
6116 ouput_egl_buffers = true;
6117 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6118 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6119 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006120 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006121 return OMX_ErrorInsufficientResources;
6122 }
6123 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006124}
6125
6126/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006127 FUNCTION
6128 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006129
Arun Menon906de572013-06-18 17:01:40 -07006130 DESCRIPTION
6131 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006132
Arun Menon906de572013-06-18 17:01:40 -07006133 PARAMETERS
6134 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006135
Arun Menon906de572013-06-18 17:01:40 -07006136 RETURN VALUE
6137 OMX Error None if everything is successful.
6138 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006139OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006140 OMX_OUT OMX_U8* role,
6141 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006142{
Arun Menon906de572013-06-18 17:01:40 -07006143 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006144
Arun Menon906de572013-06-18 17:01:40 -07006145 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6146 if ((0 == index) && role) {
6147 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006148 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006149 } else {
6150 eRet = OMX_ErrorNoMore;
6151 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006152 }
Arun Menon906de572013-06-18 17:01:40 -07006153 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6154 if ((0 == index) && role) {
6155 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006156 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006157 } else {
6158 eRet = OMX_ErrorNoMore;
6159 }
6160 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6161 if ((0 == index) && role) {
6162 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006163 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006164 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006165 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006166 eRet = OMX_ErrorNoMore;
6167 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006168 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006169
Arun Menon906de572013-06-18 17:01:40 -07006170 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6171 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6172 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006173
Shalaj Jain273b3e02012-06-22 19:08:03 -07006174 {
Arun Menon906de572013-06-18 17:01:40 -07006175 if ((0 == index) && role) {
6176 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006177 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006178 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006179 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006180 eRet = OMX_ErrorNoMore;
6181 }
6182 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6183 if ((0 == index) && role) {
6184 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006185 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006186 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006187 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006188 eRet = OMX_ErrorNoMore;
6189 }
6190 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6191 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6192 ) {
6193 if ((0 == index) && role) {
6194 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006195 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006196 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006197 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006198 eRet = OMX_ErrorNoMore;
6199 }
6200 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6201 if ((0 == index) && role) {
6202 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006203 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006204 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006205 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006206 eRet = OMX_ErrorNoMore;
6207 }
6208 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006209 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006210 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006211 }
Arun Menon906de572013-06-18 17:01:40 -07006212 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006213}
6214
6215
6216
6217
6218/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006219 FUNCTION
6220 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006221
Arun Menon906de572013-06-18 17:01:40 -07006222 DESCRIPTION
6223 Checks if entire buffer pool is allocated by IL Client or not.
6224 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006225
Arun Menon906de572013-06-18 17:01:40 -07006226 PARAMETERS
6227 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006228
Arun Menon906de572013-06-18 17:01:40 -07006229 RETURN VALUE
6230 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006231
Arun Menon906de572013-06-18 17:01:40 -07006232 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006233bool omx_vdec::allocate_done(void)
6234{
Arun Menon906de572013-06-18 17:01:40 -07006235 bool bRet = false;
6236 bool bRet_In = false;
6237 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006238
Arun Menon906de572013-06-18 17:01:40 -07006239 bRet_In = allocate_input_done();
6240 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006241
Arun Menon906de572013-06-18 17:01:40 -07006242 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006243 bRet = true;
6244 }
Arun Menon906de572013-06-18 17:01:40 -07006245
6246 return bRet;
6247}
6248/* ======================================================================
6249 FUNCTION
6250 omx_vdec::AllocateInputDone
6251
6252 DESCRIPTION
6253 Checks if I/P buffer pool is allocated by IL Client or not.
6254
6255 PARAMETERS
6256 None.
6257
6258 RETURN VALUE
6259 true/false.
6260
6261 ========================================================================== */
6262bool omx_vdec::allocate_input_done(void)
6263{
6264 bool bRet = false;
6265 unsigned i=0;
6266
6267 if (m_inp_mem_ptr == NULL) {
6268 return bRet;
6269 }
6270 if (m_inp_mem_ptr ) {
6271 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6272 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6273 break;
6274 }
6275 }
6276 }
6277 if (i == drv_ctx.ip_buf.actualcount) {
6278 bRet = true;
6279 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6280 }
6281 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6282 m_inp_bPopulated = OMX_TRUE;
6283 }
6284 return bRet;
6285}
6286/* ======================================================================
6287 FUNCTION
6288 omx_vdec::AllocateOutputDone
6289
6290 DESCRIPTION
6291 Checks if entire O/P buffer pool is allocated by IL Client or not.
6292
6293 PARAMETERS
6294 None.
6295
6296 RETURN VALUE
6297 true/false.
6298
6299 ========================================================================== */
6300bool omx_vdec::allocate_output_done(void)
6301{
6302 bool bRet = false;
6303 unsigned j=0;
6304
6305 if (m_out_mem_ptr == NULL) {
6306 return bRet;
6307 }
6308
6309 if (m_out_mem_ptr) {
6310 for (; j < drv_ctx.op_buf.actualcount; j++) {
6311 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6312 break;
6313 }
6314 }
6315 }
6316
6317 if (j == drv_ctx.op_buf.actualcount) {
6318 bRet = true;
6319 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6320 if (m_out_bEnabled)
6321 m_out_bPopulated = OMX_TRUE;
6322 }
6323
6324 return bRet;
6325}
6326
6327/* ======================================================================
6328 FUNCTION
6329 omx_vdec::ReleaseDone
6330
6331 DESCRIPTION
6332 Checks if IL client has released all the buffers.
6333
6334 PARAMETERS
6335 None.
6336
6337 RETURN VALUE
6338 true/false
6339
6340 ========================================================================== */
6341bool omx_vdec::release_done(void)
6342{
6343 bool bRet = false;
6344
6345 if (release_input_done()) {
6346 if (release_output_done()) {
6347 bRet = true;
6348 }
6349 }
6350 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006351}
6352
6353
6354/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006355 FUNCTION
6356 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006357
Arun Menon906de572013-06-18 17:01:40 -07006358 DESCRIPTION
6359 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006360
Arun Menon906de572013-06-18 17:01:40 -07006361 PARAMETERS
6362 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006363
Arun Menon906de572013-06-18 17:01:40 -07006364 RETURN VALUE
6365 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006366
Arun Menon906de572013-06-18 17:01:40 -07006367 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006368bool omx_vdec::release_output_done(void)
6369{
Arun Menon906de572013-06-18 17:01:40 -07006370 bool bRet = false;
6371 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006372
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006373 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006374 if (m_out_mem_ptr) {
6375 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6376 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6377 break;
6378 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006379 }
Arun Menon906de572013-06-18 17:01:40 -07006380 if (j == drv_ctx.op_buf.actualcount) {
6381 m_out_bm_count = 0;
6382 bRet = true;
6383 }
6384 } else {
6385 m_out_bm_count = 0;
6386 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006387 }
Arun Menon906de572013-06-18 17:01:40 -07006388 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006389}
6390/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006391 FUNCTION
6392 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006393
Arun Menon906de572013-06-18 17:01:40 -07006394 DESCRIPTION
6395 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006396
Arun Menon906de572013-06-18 17:01:40 -07006397 PARAMETERS
6398 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006399
Arun Menon906de572013-06-18 17:01:40 -07006400 RETURN VALUE
6401 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006402
Arun Menon906de572013-06-18 17:01:40 -07006403 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006404bool omx_vdec::release_input_done(void)
6405{
Arun Menon906de572013-06-18 17:01:40 -07006406 bool bRet = false;
6407 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006408
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006409 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006410 if (m_inp_mem_ptr) {
6411 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6412 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6413 break;
6414 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006415 }
Arun Menon906de572013-06-18 17:01:40 -07006416 if (j==drv_ctx.ip_buf.actualcount) {
6417 bRet = true;
6418 }
6419 } else {
6420 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006421 }
Arun Menon906de572013-06-18 17:01:40 -07006422 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006423}
6424
6425OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006426 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006427{
Arun Menon906de572013-06-18 17:01:40 -07006428 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306429 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006430 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006431 return OMX_ErrorBadParameter;
6432 } else if (output_flush_progress) {
6433 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6434 buffer->nFilledLen = 0;
6435 buffer->nTimeStamp = 0;
6436 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6437 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6438 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006439 }
6440
Arun Menon906de572013-06-18 17:01:40 -07006441 if (m_debug_extradata) {
6442 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006443 DEBUG_PRINT_HIGH("");
6444 DEBUG_PRINT_HIGH("***************************************************");
6445 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6446 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006447 }
6448
6449 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006450 DEBUG_PRINT_HIGH("");
6451 DEBUG_PRINT_HIGH("***************************************************");
6452 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6453 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006454 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006455 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006456
6457
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006458 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006459 buffer, buffer->pBuffer);
6460 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006461
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006462 if (dynamic_buf_mode) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006463 unsigned int nPortIndex = 0;
6464 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
ApurupaPattapuf693a4d2013-12-04 16:07:07 -08006465
6466 if (!secure_mode) {
6467 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6468 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6469 }
6470
6471 //Clear graphic buffer handles in dynamic mode
6472 native_buffer[nPortIndex].privatehandle = NULL;
6473 native_buffer[nPortIndex].nativehandle = NULL;
Arun Menonbdb80b02013-08-12 17:45:54 -07006474 }
Arun Menon906de572013-06-18 17:01:40 -07006475 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006476 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006477 if (!output_flush_progress)
6478 post_event((unsigned)NULL, (unsigned)NULL,
6479 OMX_COMPONENT_GENERATE_EOS_DONE);
6480
6481 if (psource_frame) {
6482 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6483 psource_frame = NULL;
6484 }
6485 if (pdest_frame) {
6486 pdest_frame->nFilledLen = 0;
6487 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6488 (unsigned)NULL);
6489 pdest_frame = NULL;
6490 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006491 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006492
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006493 DEBUG_PRINT_LOW("In fill Buffer done call address %p ",buffer);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006494 log_output_buffers(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006495
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006496 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6497 DEBUG_PRINT_LOW("Processing extradata");
6498 handle_extradata(buffer);
6499 }
6500
Arun Menon906de572013-06-18 17:01:40 -07006501 /* For use buffer we need to copy the data */
6502 if (!output_flush_progress) {
6503 /* This is the error check for non-recoverable errros */
6504 bool is_duplicate_ts_valid = true;
6505 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006506
Arun Menon906de572013-06-18 17:01:40 -07006507 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6508 output_capability == V4L2_PIX_FMT_MPEG2 ||
6509 output_capability == V4L2_PIX_FMT_DIVX ||
6510 output_capability == V4L2_PIX_FMT_DIVX_311)
6511 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006512
Arun Menon906de572013-06-18 17:01:40 -07006513 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6514 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6515 if (mbaff) {
6516 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306517 }
Arun Menon906de572013-06-18 17:01:40 -07006518 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306519
Arun Menon906de572013-06-18 17:01:40 -07006520 if (buffer->nFilledLen > 0) {
6521 time_stamp_dts.get_next_timestamp(buffer,
6522 is_interlaced && is_duplicate_ts_valid);
6523 if (m_debug_timestamp) {
6524 {
6525 OMX_TICKS expected_ts = 0;
6526 m_timestamp_list.pop_min_ts(expected_ts);
6527 if (is_interlaced && is_duplicate_ts_valid) {
6528 m_timestamp_list.pop_min_ts(expected_ts);
6529 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006530 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006531 buffer->nTimeStamp, expected_ts);
6532
6533 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006534 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006535 }
6536 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306537 }
Arun Menon906de572013-06-18 17:01:40 -07006538 } else {
6539 m_inp_err_count++;
6540 time_stamp_dts.remove_time_stamp(
6541 buffer->nTimeStamp,
6542 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306543 }
Arun Menon906de572013-06-18 17:01:40 -07006544
6545
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006546 }
Arun Menon906de572013-06-18 17:01:40 -07006547 if (m_cb.FillBufferDone) {
6548 if (buffer->nFilledLen > 0) {
Arun Menon906de572013-06-18 17:01:40 -07006549 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6550 set_frame_rate(buffer->nTimeStamp);
6551 else if (arbitrary_bytes)
6552 adjust_timestamp(buffer->nTimeStamp);
6553 if (perf_flag) {
6554 if (!proc_frms) {
6555 dec_time.stop();
6556 latency = dec_time.processing_time_us() - latency;
6557 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6558 dec_time.start();
6559 fps_metrics.start();
6560 }
6561 proc_frms++;
6562 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6563 OMX_U64 proc_time = 0;
6564 fps_metrics.stop();
6565 proc_time = fps_metrics.processing_time_us();
6566 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006567 proc_frms, (float)proc_time / 1e6,
6568 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006569 proc_frms = 0;
6570 }
6571 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006572
6573#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006574 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006575
Arun Menon906de572013-06-18 17:01:40 -07006576 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6577 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6578 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6579 buffer->nFilledLen + 3)&(~3));
6580 while (p_extra &&
6581 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006582 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006583 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6584 if (p_extra->eType == OMX_ExtraDataNone) {
6585 break;
6586 }
6587 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6588 }
6589 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006590#endif
Arun Menon906de572013-06-18 17:01:40 -07006591 }
6592 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6593 prev_ts = LLONG_MAX;
6594 rst_prev_ts = true;
6595 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006596
Arun Menon906de572013-06-18 17:01:40 -07006597 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6598 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6599 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006600 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006601 OMX_BUFFERHEADERTYPE *il_buffer;
6602 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6603 if (il_buffer)
6604 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6605 else {
6606 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6607 return OMX_ErrorBadParameter;
6608 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006609 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006610 } else {
6611 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006612 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006613
Praveen Chavancf924182013-12-06 23:16:23 -08006614#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
6615 if (m_smoothstreaming_mode) {
6616 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6617 BufferDim_t dim;
6618 dim.sliceWidth = drv_ctx.video_resolution.frame_width;
6619 dim.sliceHeight = drv_ctx.video_resolution.frame_height;
6620 private_handle_t *private_handle = native_buffer[buf_index].privatehandle;
6621 if (private_handle) {
6622 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6623 dim.sliceWidth, dim.sliceHeight);
6624 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6625 }
6626 }
6627#endif
6628
Arun Menon906de572013-06-18 17:01:40 -07006629 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006630}
6631
6632OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006633 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006634{
6635
Surajit Podderd2644d52013-08-28 17:59:06 +05306636 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006637 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006638 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006639 }
6640
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006641 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006642 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006643 pending_input_buffers--;
6644
Arun Menon906de572013-06-18 17:01:40 -07006645 if (arbitrary_bytes) {
6646 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006647 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006648 pdest_frame = buffer;
6649 buffer->nFilledLen = 0;
6650 buffer->nTimeStamp = LLONG_MAX;
6651 push_input_buffer (hComp);
6652 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006653 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006654 buffer->nFilledLen = 0;
6655 if (!m_input_free_q.insert_entry((unsigned)buffer,
6656 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006657 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006658 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006659 }
Arun Menon906de572013-06-18 17:01:40 -07006660 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006661 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006662 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006663 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6664 }
6665 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6666 }
6667 return OMX_ErrorNone;
6668}
6669
Shalaj Jain273b3e02012-06-22 19:08:03 -07006670int omx_vdec::async_message_process (void *context, void* message)
6671{
Arun Menon906de572013-06-18 17:01:40 -07006672 omx_vdec* omx = NULL;
6673 struct vdec_msginfo *vdec_msg = NULL;
6674 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6675 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6676 struct vdec_output_frameinfo *output_respbuf = NULL;
6677 int rc=1;
6678 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006679 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006680 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006681 }
Arun Menon906de572013-06-18 17:01:40 -07006682 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006683
Arun Menon906de572013-06-18 17:01:40 -07006684 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006685
Arun Menon906de572013-06-18 17:01:40 -07006686 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006687
Arun Menon906de572013-06-18 17:01:40 -07006688 case VDEC_MSG_EVT_HW_ERROR:
6689 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6690 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6691 break;
6692
6693 case VDEC_MSG_RESP_START_DONE:
6694 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6695 OMX_COMPONENT_GENERATE_START_DONE);
6696 break;
6697
6698 case VDEC_MSG_RESP_STOP_DONE:
6699 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6700 OMX_COMPONENT_GENERATE_STOP_DONE);
6701 break;
6702
6703 case VDEC_MSG_RESP_RESUME_DONE:
6704 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6705 OMX_COMPONENT_GENERATE_RESUME_DONE);
6706 break;
6707
6708 case VDEC_MSG_RESP_PAUSE_DONE:
6709 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6710 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6711 break;
6712
6713 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6714 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6715 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6716 break;
6717 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6718 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6719 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6720 break;
6721 case VDEC_MSG_RESP_INPUT_FLUSHED:
6722 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6723
6724 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6725 vdec_msg->msgdata.input_frame_clientdata; */
6726
6727 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6728 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6729 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05306730 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07006731 omxhdr = NULL;
6732 vdec_msg->status_code = VDEC_S_EFATAL;
6733 }
6734 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6735 DEBUG_PRINT_HIGH("Unsupported input");
6736 omx->omx_report_error ();
6737 }
6738 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6739 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6740 }
6741 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6742 OMX_COMPONENT_GENERATE_EBD);
6743 break;
6744 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6745 int64_t *timestamp;
6746 timestamp = (int64_t *) malloc(sizeof(int64_t));
6747 if (timestamp) {
6748 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6749 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6750 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006751 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07006752 vdec_msg->msgdata.output_frame.time_stamp);
6753 }
6754 break;
6755 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6756 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6757
6758 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6759 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6760 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6761 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6762 vdec_msg->msgdata.output_frame.pic_type);
6763
6764 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306765 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07006766 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05306767 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006768 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6769 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6770 }
Arun Menon906de572013-06-18 17:01:40 -07006771 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6772 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6773 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6774 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6775 omxhdr->nFlags = 0;
6776
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006777 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006778 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6779 //rc = -1;
6780 }
6781 if (omxhdr->nFilledLen) {
6782 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6783 }
6784 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6785 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6786 } else {
6787 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6788 }
6789 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6790 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6791 }
6792 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6793 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6794 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006795 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006796 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006797 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6798 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6799 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006800 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6801 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6802 omxhdr->nOffset);
6803 }
Arun Menon906de572013-06-18 17:01:40 -07006804 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6805 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006806 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006807 omx->time_stamp_dts.remove_time_stamp(
6808 omxhdr->nTimeStamp,
6809 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6810 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006811 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6812 OMX_COMPONENT_GENERATE_FTB);
6813 break;
6814 }
6815 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6816 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6817 }
6818 vdec_msg->msgdata.output_frame.bufferaddr =
6819 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6820 int format_notably_changed = 0;
6821 if (omxhdr->nFilledLen &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306822 (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) {
Arun Menon906de572013-06-18 17:01:40 -07006823 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6824 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006825 DEBUG_PRINT_HIGH("Height/Width information has changed");
Arun Menon906de572013-06-18 17:01:40 -07006826 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6827 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6828 format_notably_changed = 1;
6829 }
6830 }
6831 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6832 vdec_msg->msgdata.output_frame.framesize.left)
6833 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6834 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6835 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6836 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6837 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6838 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6839 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006840 DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
Arun Menon906de572013-06-18 17:01:40 -07006841 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6842 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6843 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006844 DEBUG_PRINT_HIGH("Crop information changed. W: %lu --> %d, H: %lu -> %d",
Arun Menon906de572013-06-18 17:01:40 -07006845 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6846 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006847 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6848 omx->drv_ctx.video_resolution.frame_width) {
6849 vdec_msg->msgdata.output_frame.framesize.left = 0;
6850 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6851 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6852 }
6853 }
6854 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6855 omx->drv_ctx.video_resolution.frame_height) {
6856 vdec_msg->msgdata.output_frame.framesize.top = 0;
6857 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6858 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6859 }
6860 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006861 DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006862 vdec_msg->msgdata.output_frame.framesize.left,
6863 vdec_msg->msgdata.output_frame.framesize.top,
6864 vdec_msg->msgdata.output_frame.framesize.right,
6865 vdec_msg->msgdata.output_frame.framesize.bottom,
6866 omx->drv_ctx.video_resolution.frame_width,
6867 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006868 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6869 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6870 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6871 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6872 format_notably_changed = 1;
6873 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006874 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006875 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6876 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006877 if (format_notably_changed) {
6878 if (omx->is_video_session_supported()) {
Surajit Podderd2644d52013-08-28 17:59:06 +05306879 omx->post_event (0, vdec_msg->status_code,
Arun Menon906de572013-06-18 17:01:40 -07006880 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6881 } else {
6882 if (!omx->client_buffers.update_buffer_req()) {
6883 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6884 }
6885 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6886 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6887 }
6888 }
6889 if (omxhdr->nFilledLen)
6890 omx->prev_n_filled_len = omxhdr->nFilledLen;
6891
6892 output_respbuf = (struct vdec_output_frameinfo *)\
6893 omxhdr->pOutputPortPrivate;
6894 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6895 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6896 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6897 output_respbuf->pic_type = PICTURE_TYPE_I;
6898 }
6899 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6900 output_respbuf->pic_type = PICTURE_TYPE_P;
6901 }
6902 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6903 output_respbuf->pic_type = PICTURE_TYPE_B;
6904 }
6905
6906 if (omx->output_use_buffer)
6907 memcpy ( omxhdr->pBuffer, (void *)
6908 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6909 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6910 vdec_msg->msgdata.output_frame.len);
6911 } else
6912 omxhdr->nFilledLen = 0;
6913 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6914 OMX_COMPONENT_GENERATE_FBD);
6915 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6916 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6917 OMX_COMPONENT_GENERATE_EOS_DONE);
6918 else
6919 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6920 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6921 break;
6922 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006923 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07006924 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6925 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6926 break;
6927 default:
6928 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006929 }
Arun Menon906de572013-06-18 17:01:40 -07006930 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006931}
6932
6933OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006934 OMX_HANDLETYPE hComp,
6935 OMX_BUFFERHEADERTYPE *buffer
6936 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006937{
Arun Menon906de572013-06-18 17:01:40 -07006938 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006939 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006940
Arun Menon906de572013-06-18 17:01:40 -07006941 if (buffer == NULL) {
6942 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006943 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006944 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6945 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07006946 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6947
6948 /* return zero length and not an EOS buffer */
6949 /* return buffer if input flush in progress */
6950 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6951 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006952 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07006953 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6954 return OMX_ErrorNone;
6955 }
6956
6957 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006958 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07006959 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006960 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07006961 push_input_buffer (hComp);
6962 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006963 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006964 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6965 (unsigned)NULL)) {
6966 return OMX_ErrorBadParameter;
6967 }
6968 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006969
6970
Arun Menon906de572013-06-18 17:01:40 -07006971 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006972}
6973
6974OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6975{
Arun Menon906de572013-06-18 17:01:40 -07006976 unsigned address,p2,id;
6977 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006978
Arun Menon906de572013-06-18 17:01:40 -07006979 if (pdest_frame == NULL || psource_frame == NULL) {
6980 /*Check if we have a destination buffer*/
6981 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006982 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07006983 if (m_input_free_q.m_size) {
6984 m_input_free_q.pop_entry(&address,&p2,&id);
6985 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6986 pdest_frame->nFilledLen = 0;
6987 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006988 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07006989 }
6990 }
6991
6992 /*Check if we have a destination buffer*/
6993 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006994 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07006995 if (m_input_pending_q.m_size) {
6996 m_input_pending_q.pop_entry(&address,&p2,&id);
6997 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006998 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07006999 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007000 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007001 psource_frame->nFlags,psource_frame->nFilledLen);
7002
7003 }
7004 }
7005
Shalaj Jain273b3e02012-06-22 19:08:03 -07007006 }
7007
Arun Menon906de572013-06-18 17:01:40 -07007008 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
7009 switch (codec_type_parse) {
7010 case CODEC_TYPE_MPEG4:
7011 case CODEC_TYPE_H263:
7012 case CODEC_TYPE_MPEG2:
7013 ret = push_input_sc_codec(hComp);
7014 break;
7015 case CODEC_TYPE_H264:
7016 ret = push_input_h264(hComp);
7017 break;
7018 case CODEC_TYPE_VC1:
7019 ret = push_input_vc1(hComp);
7020 break;
7021 default:
7022 break;
7023 }
7024 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007025 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07007026 omx_report_error ();
7027 break;
7028 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007029 }
7030
Arun Menon906de572013-06-18 17:01:40 -07007031 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007032}
7033
7034OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7035{
Arun Menon906de572013-06-18 17:01:40 -07007036 OMX_U32 partial_frame = 1;
7037 OMX_BOOL generate_ebd = OMX_TRUE;
7038 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007039
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007040 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007041 psource_frame,psource_frame->nTimeStamp);
7042 if (m_frame_parser.parse_sc_frame(psource_frame,
7043 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007044 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007045 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007046 }
Arun Menon906de572013-06-18 17:01:40 -07007047
7048 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007049 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007050 pdest_frame->nFilledLen,psource_frame,frame_count);
7051
7052
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007053 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007054 /*First Parsed buffer will have only header Hence skip*/
7055 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007056 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007057
7058 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7059 codec_type_parse == CODEC_TYPE_DIVX) {
7060 mp4StreamType psBits;
7061 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7062 psBits.numBytes = pdest_frame->nFilledLen;
7063 mp4_headerparser.parseHeader(&psBits);
7064 }
7065
7066 frame_count++;
7067 } else {
7068 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7069 if (pdest_frame->nFilledLen) {
7070 /*Push the frame to the Decoder*/
7071 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7072 return OMX_ErrorBadParameter;
7073 }
7074 frame_count++;
7075 pdest_frame = NULL;
7076
7077 if (m_input_free_q.m_size) {
7078 m_input_free_q.pop_entry(&address,&p2,&id);
7079 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7080 pdest_frame->nFilledLen = 0;
7081 }
7082 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007083 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007084 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7085 (unsigned)NULL);
7086 pdest_frame = NULL;
7087 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007088 }
Arun Menon906de572013-06-18 17:01:40 -07007089 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007090 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007091 /*Check if Destination Buffer is full*/
7092 if (pdest_frame->nAllocLen ==
7093 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007094 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007095 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007096 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007097 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007098
Arun Menon906de572013-06-18 17:01:40 -07007099 if (psource_frame->nFilledLen == 0) {
7100 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7101 if (pdest_frame) {
7102 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007103 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007104 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007105 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007106 pdest_frame->nFilledLen,frame_count++);
7107 /*Push the frame to the Decoder*/
7108 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7109 return OMX_ErrorBadParameter;
7110 }
7111 frame_count++;
7112 pdest_frame = NULL;
7113 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007114 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007115 generate_ebd = OMX_FALSE;
7116 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007117 }
Arun Menon906de572013-06-18 17:01:40 -07007118 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007119 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007120 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7121 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007122
Arun Menon906de572013-06-18 17:01:40 -07007123 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007124 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007125 m_input_pending_q.pop_entry(&address,&p2,&id);
7126 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007127 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007128 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007129 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007130 psource_frame->nFlags,psource_frame->nFilledLen);
7131 }
7132 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007133 }
Arun Menon906de572013-06-18 17:01:40 -07007134 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007135}
7136
7137OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7138{
Arun Menon906de572013-06-18 17:01:40 -07007139 OMX_U32 partial_frame = 1;
7140 unsigned address = 0, p2 = 0, id = 0;
7141 OMX_BOOL isNewFrame = OMX_FALSE;
7142 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007143
Arun Menon906de572013-06-18 17:01:40 -07007144 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007145 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007146 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007147 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007148 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007149 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007150 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007151 if (h264_scratch.nFilledLen && look_ahead_nal) {
7152 look_ahead_nal = false;
7153 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7154 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007155 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7156 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7157 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007158 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007159 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007160 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007161 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007162 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007163 }
Arun Menon906de572013-06-18 17:01:40 -07007164 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007165
7166 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7167 in EOS flag getting associated with the destination
7168 */
7169 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7170 pdest_frame->nFilledLen) {
7171 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7172 generate_ebd = OMX_FALSE;
7173 }
7174
Arun Menon906de572013-06-18 17:01:40 -07007175 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007176 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007177 if (m_frame_parser.parse_sc_frame(psource_frame,
7178 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007179 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007180 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007181 }
Arun Menon906de572013-06-18 17:01:40 -07007182 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007183 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007184 if (m_frame_parser.parse_h264_nallength(psource_frame,
7185 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007186 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007187 return OMX_ErrorBadParameter;
7188 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007189 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007190
Arun Menon906de572013-06-18 17:01:40 -07007191 if (partial_frame == 0) {
7192 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007193 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007194 nal_count++;
7195 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7196 h264_scratch.nFlags = psource_frame->nFlags;
7197 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007198 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007199 if (h264_scratch.nFilledLen) {
7200 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7201 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007202#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007203 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7204 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7205 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7206 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7207 // If timeinfo is present frame info from SEI is already processed
7208 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7209 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007210#endif
Arun Menon906de572013-06-18 17:01:40 -07007211 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7212 nal_count++;
7213 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7214 pdest_frame->nTimeStamp = h264_last_au_ts;
7215 pdest_frame->nFlags = h264_last_au_flags;
7216#ifdef PANSCAN_HDLR
7217 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7218 h264_parser->update_panscan_data(h264_last_au_ts);
7219#endif
7220 }
7221 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7222 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7223 h264_last_au_ts = h264_scratch.nTimeStamp;
7224 h264_last_au_flags = h264_scratch.nFlags;
7225#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7226 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7227 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7228 if (!VALID_TS(h264_last_au_ts))
7229 h264_last_au_ts = ts_in_sei;
7230 }
7231#endif
7232 } else
7233 h264_last_au_ts = LLONG_MAX;
7234 }
7235
7236 if (!isNewFrame) {
7237 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7238 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007239 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007240 h264_scratch.nFilledLen);
7241 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7242 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7243 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7244 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7245 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7246 h264_scratch.nFilledLen = 0;
7247 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007248 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007249 return OMX_ErrorBadParameter;
7250 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007251 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007252 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007253 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007254 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007255 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007256 pdest_frame->nFilledLen,frame_count++);
7257
7258 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007259 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007260 look_ahead_nal = false;
7261 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7262 h264_scratch.nFilledLen) {
7263 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7264 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7265 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7266 h264_scratch.nFilledLen = 0;
7267 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007268 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007269 return OMX_ErrorBadParameter;
7270 }
7271 } else {
7272 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007273 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007274 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7275 }
7276 /*Push the frame to the Decoder*/
7277 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7278 return OMX_ErrorBadParameter;
7279 }
7280 //frame_count++;
7281 pdest_frame = NULL;
7282 if (m_input_free_q.m_size) {
7283 m_input_free_q.pop_entry(&address,&p2,&id);
7284 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007285 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007286 pdest_frame->nFilledLen = 0;
7287 pdest_frame->nFlags = 0;
7288 pdest_frame->nTimeStamp = LLONG_MAX;
7289 }
7290 }
7291 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007292 }
Arun Menon906de572013-06-18 17:01:40 -07007293 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007294 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007295 /*Check if Destination Buffer is full*/
7296 if (h264_scratch.nAllocLen ==
7297 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007298 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007299 return OMX_ErrorStreamCorrupt;
7300 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007301 }
Arun Menon906de572013-06-18 17:01:40 -07007302
7303 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007304 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007305
7306 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7307 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007308 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007309 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7310 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007311 if(pdest_frame->nFilledLen == 0) {
7312 /* No residual frame from before, send whatever
7313 * we have left */
7314 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7315 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7316 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7317 h264_scratch.nFilledLen = 0;
7318 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7319 } else {
7320 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7321 if(!isNewFrame) {
7322 /* Have a residual frame, but we know that the
7323 * AU in this frame is belonging to whatever
7324 * frame we had left over. So append it */
7325 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7326 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7327 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7328 h264_scratch.nFilledLen = 0;
7329 pdest_frame->nTimeStamp = h264_last_au_ts;
7330 } else {
7331 /* Completely new frame, let's just push what
7332 * we have now. The resulting EBD would trigger
7333 * another push */
7334 generate_ebd = OMX_FALSE;
7335 pdest_frame->nTimeStamp = h264_last_au_ts;
7336 h264_last_au_ts = h264_scratch.nTimeStamp;
7337 }
7338 }
Arun Menon906de572013-06-18 17:01:40 -07007339 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007340 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007341 return OMX_ErrorBadParameter;
7342 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007343
7344 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7345 if(generate_ebd == OMX_TRUE) {
7346 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7347 }
Arun Menon906de572013-06-18 17:01:40 -07007348
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007349 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007350 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007351 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007352#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7353 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7354 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7355 if (!VALID_TS(pdest_frame->nTimeStamp))
7356 pdest_frame->nTimeStamp = ts_in_sei;
7357 }
7358#endif
7359 /*Push the frame to the Decoder*/
7360 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7361 return OMX_ErrorBadParameter;
7362 }
7363 frame_count++;
7364 pdest_frame = NULL;
7365 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007366 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007367 pdest_frame,h264_scratch.nFilledLen);
7368 generate_ebd = OMX_FALSE;
7369 }
7370 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007371 }
Arun Menon906de572013-06-18 17:01:40 -07007372 if (generate_ebd && !psource_frame->nFilledLen) {
7373 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7374 psource_frame = NULL;
7375 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007376 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007377 m_input_pending_q.pop_entry(&address,&p2,&id);
7378 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007379 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007380 psource_frame->nFlags,psource_frame->nFilledLen);
7381 }
7382 }
7383 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007384}
7385
7386OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7387{
7388 OMX_U8 *buf, *pdest;
7389 OMX_U32 partial_frame = 1;
7390 OMX_U32 buf_len, dest_len;
7391
Arun Menon906de572013-06-18 17:01:40 -07007392 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007393 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007394 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007395 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007396 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007397 buf = psource_frame->pBuffer;
7398 buf_len = psource_frame->nFilledLen;
7399
7400 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007401 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007402 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007403 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007404 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007405 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007406 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007407 return OMX_ErrorStreamCorrupt;
7408 }
Arun Menon906de572013-06-18 17:01:40 -07007409 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007410 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7411 pdest_frame->nOffset;
7412 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007413 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007414
Arun Menon906de572013-06-18 17:01:40 -07007415 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007416 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007417 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007418 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007419 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7420 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7421 }
7422 }
7423 }
7424
Arun Menon906de572013-06-18 17:01:40 -07007425 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007426 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007427 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007428 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007429 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007430 return OMX_ErrorBadParameter;
7431 }
Arun Menon906de572013-06-18 17:01:40 -07007432 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007433
7434 case VC1_SP_MP_RCV:
7435 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007436 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007437 return OMX_ErrorBadParameter;
7438 }
7439 return OMX_ErrorNone;
7440}
7441
David Ng38e2d232013-03-15 20:05:58 -07007442#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007443bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007444 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007445{
Arun Menon906de572013-06-18 17:01:40 -07007446 struct pmem_allocation allocation;
7447 allocation.size = buffer_size;
7448 allocation.align = clip2(alignment);
7449 if (allocation.align < 4096) {
7450 allocation.align = 4096;
7451 }
7452 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007453 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007454 allocation.align, allocation.size);
7455 return false;
7456 }
7457 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007458}
David Ng38e2d232013-03-15 20:05:58 -07007459#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007460#ifdef USE_ION
7461int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007462 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7463 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007464{
Arun Menon906de572013-06-18 17:01:40 -07007465 int fd = -EINVAL;
7466 int rc = -EINVAL;
7467 int ion_dev_flag;
7468 struct vdec_ion ion_buf_info;
7469 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007470 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007471 return -EINVAL;
7472 }
7473 ion_dev_flag = O_RDONLY;
7474 fd = open (MEM_DEVICE, ion_dev_flag);
7475 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007476 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007477 return fd;
7478 }
7479 alloc_data->flags = 0;
7480 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7481 alloc_data->flags |= ION_FLAG_CACHED;
7482 }
7483 alloc_data->len = buffer_size;
7484 alloc_data->align = clip2(alignment);
7485 if (alloc_data->align < 4096) {
7486 alloc_data->align = 4096;
7487 }
7488 if ((secure_mode) && (flag & ION_SECURE))
7489 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007490
Arun Menon906de572013-06-18 17:01:40 -07007491 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307492 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007493 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7494 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7495 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007496 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007497 alloc_data->handle = NULL;
7498 close(fd);
7499 fd = -ENOMEM;
7500 return fd;
7501 }
7502 fd_data->handle = alloc_data->handle;
7503 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7504 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007505 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007506 ion_buf_info.ion_alloc_data = *alloc_data;
7507 ion_buf_info.ion_device_fd = fd;
7508 ion_buf_info.fd_ion_data = *fd_data;
7509 free_ion_memory(&ion_buf_info);
7510 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007511 fd = -ENOMEM;
7512 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007513
Arun Menon906de572013-06-18 17:01:40 -07007514 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007515}
7516
Arun Menon906de572013-06-18 17:01:40 -07007517void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7518{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007519
Arun Menon906de572013-06-18 17:01:40 -07007520 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007521 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007522 return;
7523 }
7524 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7525 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007526 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007527 }
7528 close(buf_ion_info->ion_device_fd);
7529 buf_ion_info->ion_device_fd = -1;
7530 buf_ion_info->ion_alloc_data.handle = NULL;
7531 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007532}
7533#endif
7534void omx_vdec::free_output_buffer_header()
7535{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007536 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007537 output_use_buffer = false;
7538 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007539
Arun Menon906de572013-06-18 17:01:40 -07007540 if (m_out_mem_ptr) {
7541 free (m_out_mem_ptr);
7542 m_out_mem_ptr = NULL;
7543 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007544
Arun Menon906de572013-06-18 17:01:40 -07007545 if (m_platform_list) {
7546 free(m_platform_list);
7547 m_platform_list = NULL;
7548 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007549
Arun Menon906de572013-06-18 17:01:40 -07007550 if (drv_ctx.ptr_respbuffer) {
7551 free (drv_ctx.ptr_respbuffer);
7552 drv_ctx.ptr_respbuffer = NULL;
7553 }
7554 if (drv_ctx.ptr_outputbuffer) {
7555 free (drv_ctx.ptr_outputbuffer);
7556 drv_ctx.ptr_outputbuffer = NULL;
7557 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007558#ifdef USE_ION
7559 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007560 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007561 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007562 drv_ctx.op_buf_ion_info = NULL;
7563 }
7564#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007565 if (out_dynamic_list) {
7566 free(out_dynamic_list);
7567 out_dynamic_list = NULL;
7568 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007569}
7570
7571void omx_vdec::free_input_buffer_header()
7572{
7573 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007574 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007575 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007576 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007577 free (m_inp_heap_ptr);
7578 m_inp_heap_ptr = NULL;
7579 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007580
Arun Menon906de572013-06-18 17:01:40 -07007581 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007582 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007583 free (m_phdr_pmem_ptr);
7584 m_phdr_pmem_ptr = NULL;
7585 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007586 }
Arun Menon906de572013-06-18 17:01:40 -07007587 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007588 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007589 free (m_inp_mem_ptr);
7590 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007591 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007592 /* We just freed all the buffer headers, every thing in m_input_free_q,
7593 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007594 while (m_input_free_q.m_size) {
7595 unsigned address, p2, id;
7596 m_input_free_q.pop_entry(&address, &p2, &id);
7597 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007598 while (m_input_pending_q.m_size) {
7599 unsigned address, p2, id;
7600 m_input_pending_q.pop_entry(&address, &p2, &id);
7601 }
7602 pdest_frame = NULL;
7603 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007604 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007605 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007606 free (drv_ctx.ptr_inputbuffer);
7607 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007608 }
7609#ifdef USE_ION
7610 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007611 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007612 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007613 drv_ctx.ip_buf_ion_info = NULL;
7614 }
7615#endif
7616}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007617
7618int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007619{
Arun Menon906de572013-06-18 17:01:40 -07007620 enum v4l2_buf_type btype;
7621 int rc = 0;
7622 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007623
Arun Menon906de572013-06-18 17:01:40 -07007624 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7625 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7626 v4l2_port = OUTPUT_PORT;
7627 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7628 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7629 v4l2_port = CAPTURE_PORT;
7630 } else if (port == OMX_ALL) {
7631 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7632 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007633
Arun Menon906de572013-06-18 17:01:40 -07007634 if (!rc_input)
7635 return rc_input;
7636 else
7637 return rc_output;
7638 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007639
Arun Menon906de572013-06-18 17:01:40 -07007640 if (!streaming[v4l2_port]) {
7641 // already streamed off, warn and move on
7642 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7643 " which is already streamed off", v4l2_port);
7644 return 0;
7645 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007646
Arun Menon906de572013-06-18 17:01:40 -07007647 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007648
Arun Menon906de572013-06-18 17:01:40 -07007649 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7650 if (rc) {
7651 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007652 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007653 } else {
7654 streaming[v4l2_port] = false;
7655 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007656
Arun Menon906de572013-06-18 17:01:40 -07007657 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007658}
7659
7660OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7661{
Arun Menon906de572013-06-18 17:01:40 -07007662 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7663 struct v4l2_requestbuffers bufreq;
7664 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7665 struct v4l2_format fmt;
7666 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007667 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007668 buffer_prop->actualcount, buffer_prop->buffer_size);
7669 bufreq.memory = V4L2_MEMORY_USERPTR;
7670 bufreq.count = 1;
7671 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7672 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7673 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7674 fmt.fmt.pix_mp.pixelformat = output_capability;
7675 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7676 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7677 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7678 fmt.fmt.pix_mp.pixelformat = capture_capability;
7679 } else {
7680 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007681 }
Arun Menon906de572013-06-18 17:01:40 -07007682 if (eRet==OMX_ErrorNone) {
7683 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007684 }
Arun Menon906de572013-06-18 17:01:40 -07007685 if (ret) {
7686 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7687 /*TODO: How to handle this case */
7688 eRet = OMX_ErrorInsufficientResources;
7689 return eRet;
7690 } else {
7691 buffer_prop->actualcount = bufreq.count;
7692 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007693 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007694 }
Arun Menon906de572013-06-18 17:01:40 -07007695 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7696 buffer_prop->actualcount, buffer_prop->buffer_size);
7697
7698 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7699 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7700
7701 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7702
7703 update_resolution(fmt.fmt.pix_mp.width,
7704 fmt.fmt.pix_mp.height,
7705 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7706 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7707 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7708 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007709 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07007710
7711 if (ret) {
7712 /*TODO: How to handle this case */
7713 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7714 eRet = OMX_ErrorInsufficientResources;
7715 } else {
7716 int extra_idx = 0;
7717
7718 eRet = is_video_session_supported();
7719 if (eRet)
7720 return eRet;
7721
7722 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7723 buf_size = buffer_prop->buffer_size;
7724 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7725 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7726 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7727 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007728 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07007729 return OMX_ErrorBadParameter;
7730 }
7731 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7732 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7733 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7734 }
7735 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7736 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7737 }
7738 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7739 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007740 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d",
Arun Menon906de572013-06-18 17:01:40 -07007741 client_extra_data_size);
7742 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05307743 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
7744 client_extra_data_size += OMX_FRAMEPACK_EXTRADATA_SIZE;
7745 DEBUG_PRINT_HIGH("framepack extradata enabled");
7746 }
Arun Menon906de572013-06-18 17:01:40 -07007747 if (client_extra_data_size) {
7748 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7749 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7750 }
7751 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7752 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7753 drv_ctx.extradata_info.buffer_size = extra_data_size;
7754 buf_size += client_extra_data_size;
7755 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7756 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7757 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7758 if (in_reconfig) // BufReq will be set to driver when port is disabled
7759 buffer_prop->buffer_size = buf_size;
7760 else if (buf_size != buffer_prop->buffer_size) {
7761 buffer_prop->buffer_size = buf_size;
7762 eRet = set_buffer_req(buffer_prop);
7763 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007764 }
Arun Menon906de572013-06-18 17:01:40 -07007765 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7766 buffer_prop->actualcount, buffer_prop->buffer_size);
7767 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007768}
7769
7770OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7771{
Arun Menon906de572013-06-18 17:01:40 -07007772 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7773 unsigned buf_size = 0;
7774 struct v4l2_format fmt;
7775 struct v4l2_requestbuffers bufreq;
7776 int ret;
7777 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7778 buffer_prop->actualcount, buffer_prop->buffer_size);
7779 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7780 if (buf_size != buffer_prop->buffer_size) {
7781 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7782 buffer_prop->buffer_size, buf_size);
7783 eRet = OMX_ErrorBadParameter;
7784 } else {
7785 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7786 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007787
Arun Menon906de572013-06-18 17:01:40 -07007788 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7789 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7790 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07007791 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07007792 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7793 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7794 fmt.fmt.pix_mp.pixelformat = capture_capability;
7795 } else {
7796 eRet = OMX_ErrorBadParameter;
7797 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007798
Arun Menon906de572013-06-18 17:01:40 -07007799 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7800 if (ret) {
7801 /*TODO: How to handle this case */
7802 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7803 eRet = OMX_ErrorInsufficientResources;
7804 }
7805
7806 bufreq.memory = V4L2_MEMORY_USERPTR;
7807 bufreq.count = buffer_prop->actualcount;
7808 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7809 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7810 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7811 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7812 } else {
7813 eRet = OMX_ErrorBadParameter;
7814 }
7815
7816 if (eRet==OMX_ErrorNone) {
7817 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7818 }
7819
7820 if (ret) {
7821 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7822 /*TODO: How to handle this case */
7823 eRet = OMX_ErrorInsufficientResources;
7824 } else if (bufreq.count < buffer_prop->actualcount) {
7825 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7826 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7827 buffer_prop->actualcount, bufreq.count);
7828 eRet = OMX_ErrorInsufficientResources;
7829 } else {
7830 if (!client_buffers.update_buffer_req()) {
7831 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7832 eRet = OMX_ErrorInsufficientResources;
7833 }
7834 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007835 }
Arun Menon906de572013-06-18 17:01:40 -07007836 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007837}
7838
Shalaj Jain273b3e02012-06-22 19:08:03 -07007839OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7840{
Arun Menon906de572013-06-18 17:01:40 -07007841 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7842 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007843}
7844
7845OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7846{
Arun Menon906de572013-06-18 17:01:40 -07007847 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7848 if (!portDefn) {
7849 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007850 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007851 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07007852 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7853 portDefn->nSize = sizeof(portDefn);
7854 portDefn->eDomain = OMX_PortDomainVideo;
7855 if (drv_ctx.frame_rate.fps_denominator > 0)
7856 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7857 drv_ctx.frame_rate.fps_denominator;
7858 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007859 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07007860 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007861 }
Arun Menon906de572013-06-18 17:01:40 -07007862 if (0 == portDefn->nPortIndex) {
7863 portDefn->eDir = OMX_DirInput;
7864 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7865 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7866 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7867 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7868 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7869 portDefn->bEnabled = m_inp_bEnabled;
7870 portDefn->bPopulated = m_inp_bPopulated;
7871 } else if (1 == portDefn->nPortIndex) {
7872 unsigned int buf_size = 0;
7873 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007874 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07007875 return OMX_ErrorHardware;
7876 }
7877 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007878 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07007879 return OMX_ErrorHardware;
7880 }
7881 portDefn->nBufferSize = buf_size;
7882 portDefn->eDir = OMX_DirOutput;
7883 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7884 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7885 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7886 portDefn->bEnabled = m_out_bEnabled;
7887 portDefn->bPopulated = m_out_bPopulated;
7888 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007889 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07007890 return OMX_ErrorHardware;
7891 }
7892 } else {
7893 portDefn->eDir = OMX_DirMax;
7894 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7895 (int)portDefn->nPortIndex);
7896 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007897 }
Arun Menon906de572013-06-18 17:01:40 -07007898 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7899 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7900 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7901 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Maheshwar Ajja507d6552014-01-03 14:54:29 +05307902 if (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) {
7903 portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
7904 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
7905 }
7906 DEBUG_PRINT_HIGH("update_portdef(%lu): Width = %lu Height = %lu Stride = %ld "
7907 "SliceHeight = %lu eColorFormat = %lu nBufSize %lu nBufCnt %lu",
7908 portDefn->nPortIndex,
7909 portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07007910 portDefn->format.video.nFrameHeight,
7911 portDefn->format.video.nStride,
Maheshwar Ajja507d6552014-01-03 14:54:29 +05307912 portDefn->format.video.nSliceHeight,
7913 portDefn->format.video.eColorFormat,
7914 portDefn->nBufferSize,
7915 portDefn->nBufferCountActual);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007916
Maheshwar Ajja507d6552014-01-03 14:54:29 +05307917 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007918}
7919
7920OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7921{
Arun Menon906de572013-06-18 17:01:40 -07007922 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7923 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7924 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007925
Arun Menon906de572013-06-18 17:01:40 -07007926 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007927 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07007928 int nBufHdrSize = 0;
7929 int nPlatformEntrySize = 0;
7930 int nPlatformListSize = 0;
7931 int nPMEMInfoSize = 0;
7932 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7933 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7934 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007935
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007936 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007937 drv_ctx.op_buf.actualcount);
7938 nBufHdrSize = drv_ctx.op_buf.actualcount *
7939 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007940
Arun Menon906de572013-06-18 17:01:40 -07007941 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7942 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7943 nPlatformListSize = drv_ctx.op_buf.actualcount *
7944 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7945 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7946 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007947
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007948 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07007949 sizeof(OMX_BUFFERHEADERTYPE),
7950 nPMEMInfoSize,
7951 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007952 DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07007953 m_out_bm_count);
7954 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7955 // Alloc mem for platform specific info
7956 char *pPtr=NULL;
7957 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7958 nPMEMInfoSize,1);
7959 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7960 calloc (sizeof(struct vdec_bufferpayload),
7961 drv_ctx.op_buf.actualcount);
7962 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7963 calloc (sizeof (struct vdec_output_frameinfo),
7964 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007965#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007966 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7967 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007968#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007969 if (dynamic_buf_mode) {
7970 out_dynamic_list = (struct dynamic_buf_list *) \
7971 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
7972 }
Arun Menon906de572013-06-18 17:01:40 -07007973 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7974 && drv_ctx.ptr_respbuffer) {
7975 bufHdr = m_out_mem_ptr;
7976 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7977 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7978 (((char *) m_platform_list) + nPlatformListSize);
7979 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7980 (((char *) m_platform_entry) + nPlatformEntrySize);
7981 pPlatformList = m_platform_list;
7982 pPlatformEntry = m_platform_entry;
7983 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007984
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007985 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007986
Arun Menon906de572013-06-18 17:01:40 -07007987 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007988 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07007989 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007990 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07007991 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7992 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7993 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7994 // Set the values when we determine the right HxW param
7995 bufHdr->nAllocLen = 0;
7996 bufHdr->nFilledLen = 0;
7997 bufHdr->pAppPrivate = NULL;
7998 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7999 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8000 pPlatformEntry->entry = pPMEMInfo;
8001 // Initialize the Platform List
8002 pPlatformList->nEntries = 1;
8003 pPlatformList->entryList = pPlatformEntry;
8004 // Keep pBuffer NULL till vdec is opened
8005 bufHdr->pBuffer = NULL;
8006 pPMEMInfo->offset = 0;
8007 pPMEMInfo->pmem_fd = 0;
8008 bufHdr->pPlatformPrivate = pPlatformList;
8009 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008010#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008011 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008012#endif
Arun Menon906de572013-06-18 17:01:40 -07008013 /*Create a mapping between buffers*/
8014 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8015 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8016 &drv_ctx.ptr_outputbuffer[i];
8017 // Move the buffer and buffer header pointers
8018 bufHdr++;
8019 pPMEMInfo++;
8020 pPlatformEntry++;
8021 pPlatformList++;
8022 }
8023 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008024 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07008025 m_out_mem_ptr, pPtr);
8026 if (m_out_mem_ptr) {
8027 free(m_out_mem_ptr);
8028 m_out_mem_ptr = NULL;
8029 }
8030 if (pPtr) {
8031 free(pPtr);
8032 pPtr = NULL;
8033 }
8034 if (drv_ctx.ptr_outputbuffer) {
8035 free(drv_ctx.ptr_outputbuffer);
8036 drv_ctx.ptr_outputbuffer = NULL;
8037 }
8038 if (drv_ctx.ptr_respbuffer) {
8039 free(drv_ctx.ptr_respbuffer);
8040 drv_ctx.ptr_respbuffer = NULL;
8041 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008042#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008043 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008044 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008045 free(drv_ctx.op_buf_ion_info);
8046 drv_ctx.op_buf_ion_info = NULL;
8047 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008048#endif
Arun Menon906de572013-06-18 17:01:40 -07008049 eRet = OMX_ErrorInsufficientResources;
8050 }
8051 } else {
8052 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008053 }
Arun Menon906de572013-06-18 17:01:40 -07008054 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008055}
8056
8057void omx_vdec::complete_pending_buffer_done_cbs()
8058{
Arun Menon906de572013-06-18 17:01:40 -07008059 unsigned p1;
8060 unsigned p2;
8061 unsigned ident;
8062 omx_cmd_queue tmp_q, pending_bd_q;
8063 pthread_mutex_lock(&m_lock);
8064 // pop all pending GENERATE FDB from ftb queue
8065 while (m_ftb_q.m_size) {
8066 m_ftb_q.pop_entry(&p1,&p2,&ident);
8067 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8068 pending_bd_q.insert_entry(p1,p2,ident);
8069 } else {
8070 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008071 }
Arun Menon906de572013-06-18 17:01:40 -07008072 }
8073 //return all non GENERATE FDB to ftb queue
8074 while (tmp_q.m_size) {
8075 tmp_q.pop_entry(&p1,&p2,&ident);
8076 m_ftb_q.insert_entry(p1,p2,ident);
8077 }
8078 // pop all pending GENERATE EDB from etb queue
8079 while (m_etb_q.m_size) {
8080 m_etb_q.pop_entry(&p1,&p2,&ident);
8081 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8082 pending_bd_q.insert_entry(p1,p2,ident);
8083 } else {
8084 tmp_q.insert_entry(p1,p2,ident);
8085 }
8086 }
8087 //return all non GENERATE FDB to etb queue
8088 while (tmp_q.m_size) {
8089 tmp_q.pop_entry(&p1,&p2,&ident);
8090 m_etb_q.insert_entry(p1,p2,ident);
8091 }
8092 pthread_mutex_unlock(&m_lock);
8093 // process all pending buffer dones
8094 while (pending_bd_q.m_size) {
8095 pending_bd_q.pop_entry(&p1,&p2,&ident);
8096 switch (ident) {
8097 case OMX_COMPONENT_GENERATE_EBD:
8098 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008099 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008100 omx_report_error ();
8101 }
8102 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008103
Arun Menon906de572013-06-18 17:01:40 -07008104 case OMX_COMPONENT_GENERATE_FBD:
8105 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008106 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008107 omx_report_error ();
8108 }
8109 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008110 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008111 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008112}
8113
8114void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8115{
Arun Menon906de572013-06-18 17:01:40 -07008116 OMX_U32 new_frame_interval = 0;
8117 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8118 && llabs(act_timestamp - prev_ts) > 2000) {
8119 new_frame_interval = client_set_fps ? frm_int :
8120 llabs(act_timestamp - prev_ts);
8121 if (new_frame_interval < frm_int || frm_int == 0) {
8122 frm_int = new_frame_interval;
8123 if (frm_int) {
8124 drv_ctx.frame_rate.fps_numerator = 1e6;
8125 drv_ctx.frame_rate.fps_denominator = frm_int;
8126 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8127 frm_int, drv_ctx.frame_rate.fps_numerator /
8128 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008129
Arun Menon906de572013-06-18 17:01:40 -07008130 /* We need to report the difference between this FBD and the previous FBD
8131 * back to the driver for clock scaling purposes. */
8132 struct v4l2_outputparm oparm;
8133 /*XXX: we're providing timing info as seconds per frame rather than frames
8134 * per second.*/
8135 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8136 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008137
Arun Menon906de572013-06-18 17:01:40 -07008138 struct v4l2_streamparm sparm;
8139 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8140 sparm.parm.output = oparm;
8141 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8142 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8143 performance might be affected");
8144 }
8145
8146 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008147 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008148 }
Arun Menon906de572013-06-18 17:01:40 -07008149 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008150}
8151
8152void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8153{
Arun Menon906de572013-06-18 17:01:40 -07008154 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8155 prev_ts = act_timestamp;
8156 rst_prev_ts = false;
8157 } else if (VALID_TS(prev_ts)) {
8158 bool codec_cond = (drv_ctx.timestamp_adjust)?
8159 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8160 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8161 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8162 if (frm_int > 0 && codec_cond) {
8163 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8164 act_timestamp = prev_ts + frm_int;
8165 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8166 prev_ts = act_timestamp;
8167 } else
8168 set_frame_rate(act_timestamp);
8169 } else if (frm_int > 0) // In this case the frame rate was set along
8170 { // with the port definition, start ts with 0
8171 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8172 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008173 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008174}
8175
8176void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8177{
Arun Menon906de572013-06-18 17:01:40 -07008178 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8179 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308180 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008181 OMX_U32 frame_rate = 0;
8182 int consumed_len = 0;
8183 OMX_U32 num_MB_in_frame;
8184 OMX_U32 recovery_sei_flags = 1;
8185 int enable = 0;
8186 OMX_U32 mbaff = 0;
8187 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praveen Chavan61e5d162013-11-01 02:49:19 -07008188 if (buf_index >= drv_ctx.extradata_info.count) {
8189 DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
8190 buf_index, drv_ctx.extradata_info.count);
8191 return;
8192 }
Arun Menon906de572013-06-18 17:01:40 -07008193 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8194 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8195 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308196
Arun Menon906de572013-06-18 17:01:40 -07008197 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308198 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008199 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008200 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308201 if (!secure_mode)
8202 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008203 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308204 else
8205 p_extra = m_other_extradata;
8206
Arun Menon906de572013-06-18 17:01:40 -07008207 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308208
8209 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
Arun Menon906de572013-06-18 17:01:40 -07008210 p_extra = NULL;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308211 return;
8212 }
Arun Menon906de572013-06-18 17:01:40 -07008213 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
8214 if (data) {
8215 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8216 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308217 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008218 DEBUG_PRINT_LOW("Invalid extra data size");
8219 break;
8220 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308221 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008222 switch ((unsigned long)data->eType) {
8223 case EXTRADATA_INTERLACE_VIDEO:
8224 struct msm_vidc_interlace_payload *payload;
8225 payload = (struct msm_vidc_interlace_payload *)data->data;
8226 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8227 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8228 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008229 else if (payload && (payload->format == INTERLACE_FRAME_TOPFIELDFIRST ||
8230 payload->format == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8231 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8232 enable = 1;
8233 } else {
Arun Menon906de572013-06-18 17:01:40 -07008234 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8235 enable = 1;
8236 }
8237 if (m_enable_android_native_buffers)
8238 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8239 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308240 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008241 append_interlace_extradata(p_extra, payload->format);
8242 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8243 }
8244 break;
8245 case EXTRADATA_FRAME_RATE:
8246 struct msm_vidc_framerate_payload *frame_rate_payload;
8247 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8248 frame_rate = frame_rate_payload->frame_rate;
8249 break;
8250 case EXTRADATA_TIMESTAMP:
8251 struct msm_vidc_ts_payload *time_stamp_payload;
8252 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308253 time_stamp = time_stamp_payload->timestamp_lo;
8254 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8255 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008256 break;
8257 case EXTRADATA_NUM_CONCEALED_MB:
8258 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8259 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8260 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8261 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8262 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8263 break;
8264 case EXTRADATA_INDEX:
8265 int *etype;
8266 etype = (int *)(data->data);
8267 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8268 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8269 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8270 if (aspect_ratio_payload) {
8271 ((struct vdec_output_frameinfo *)
8272 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8273 ((struct vdec_output_frameinfo *)
8274 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8275 }
8276 }
8277 break;
8278 case EXTRADATA_RECOVERY_POINT_SEI:
8279 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8280 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8281 recovery_sei_flags = recovery_sei_payload->flags;
8282 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8283 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008284 DEBUG_PRINT_HIGH("");
8285 DEBUG_PRINT_HIGH("***************************************************");
8286 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8287 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008288 }
8289 break;
8290 case EXTRADATA_PANSCAN_WINDOW:
8291 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8292 break;
8293 case EXTRADATA_MPEG2_SEQDISP:
8294 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8295 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8296 if (seqdisp_payload) {
8297 m_disp_hor_size = seqdisp_payload->disp_width;
8298 m_disp_vert_size = seqdisp_payload->disp_height;
8299 }
8300 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308301 case EXTRADATA_S3D_FRAME_PACKING:
8302 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8303 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
8304 if (!secure_mode && (client_extradata & OMX_FRAMEPACK_EXTRADATA)) {
8305 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8306 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8307 }
8308 break;
Arun Menon906de572013-06-18 17:01:40 -07008309 default:
8310 goto unrecognized_extradata;
8311 }
8312 consumed_len += data->nSize;
8313 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8314 }
8315 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8316 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8317 append_frame_info_extradata(p_extra,
8318 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308319 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008320 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008321 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008322 }
8323 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008324unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07008325 if (!secure_mode && client_extradata)
8326 append_terminator_extradata(p_extra);
8327 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008328}
8329
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008330OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008331 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008332{
Arun Menon906de572013-06-18 17:01:40 -07008333 OMX_ERRORTYPE ret = OMX_ErrorNone;
8334 struct v4l2_control control;
8335 if (m_state != OMX_StateLoaded) {
8336 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8337 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008338 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008339 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008340 client_extradata, requested_extradata, enable, is_internal);
8341
8342 if (!is_internal) {
8343 if (enable)
8344 client_extradata |= requested_extradata;
8345 else
8346 client_extradata = client_extradata & ~requested_extradata;
8347 }
8348
8349 if (enable) {
8350 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8351 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8352 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8353 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8354 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008355 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008356 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308357 }
8358 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008359 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8360 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8361 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008362 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008363 }
8364 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8365 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8366 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008367 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008368 }
8369 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8370 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8371 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008372 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008373 }
8374 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8375 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8376 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008377 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008378 }
8379 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8380 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8381 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008382 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008383 }
8384 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8385 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8386 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8387 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008388 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008389 }
8390 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308391 }
8392 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008393 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8394 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8395 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008396 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008397 }
8398 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308399 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8400 if (output_capability == V4L2_PIX_FMT_H264) {
8401 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8402 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8403 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8404 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8405 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8406 }
8407 } else {
8408 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8409 }
8410 }
Arun Menon906de572013-06-18 17:01:40 -07008411 }
8412 ret = get_buffer_req(&drv_ctx.op_buf);
8413 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008414}
8415
8416OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8417{
Arun Menon906de572013-06-18 17:01:40 -07008418 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8419 OMX_U8 *data_ptr = extra->data, data = 0;
8420 while (byte_count < extra->nDataSize) {
8421 data = *data_ptr;
8422 while (data) {
8423 num_MB += (data&0x01);
8424 data >>= 1;
8425 }
8426 data_ptr++;
8427 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008428 }
Arun Menon906de572013-06-18 17:01:40 -07008429 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8430 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8431 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008432}
8433
8434void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8435{
Arun Menon906de572013-06-18 17:01:40 -07008436 if (!m_debug_extradata)
8437 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008438
8439 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308440 "============== Extra Data ==============\n"
8441 " Size: %lu\n"
8442 " Version: %lu\n"
8443 " PortIndex: %lu\n"
8444 " Type: %x\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008445 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008446 extra->nSize, extra->nVersion.nVersion,
8447 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008448
Arun Menon906de572013-06-18 17:01:40 -07008449 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8450 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8451 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308452 "------ Interlace Format ------\n"
8453 " Size: %lu\n"
8454 " Version: %lu\n"
8455 " PortIndex: %lu\n"
8456 " Is Interlace Format: %d\n"
8457 " Interlace Formats: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008458 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008459 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8460 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8461 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8462 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8463
8464 DEBUG_PRINT_HIGH(
Deepak Verma867d5132013-12-05 12:23:20 +05308465 "-------- Frame Format --------\n"
8466 " Picture Type: %d\n"
8467 " Interlace Type: %d\n"
8468 " Pan Scan Total Frame Num: %lu\n"
8469 " Concealed Macro Blocks: %lu\n"
8470 " frame rate: %lu\n"
8471 " Time Stamp: %llu\n"
8472 " Aspect Ratio X: %lu\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008473 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008474 fminfo->ePicType,
8475 fminfo->interlaceType,
8476 fminfo->panScan.numWindows,
8477 fminfo->nConcealedMacroblocks,
8478 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308479 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008480 fminfo->aspectRatio.aspectRatioX,
8481 fminfo->aspectRatio.aspectRatioY);
8482
8483 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8484 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008485 "------------------------------"
Deepak Verma867d5132013-12-05 12:23:20 +05308486 " Pan Scan Frame Num: %lu\n"
8487 " Rectangle x: %ld\n"
8488 " Rectangle y: %ld\n"
8489 " Rectangle dx: %ld\n"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008490 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008491 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8492 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8493 }
8494
8495 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308496 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8497 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8498 DEBUG_PRINT_HIGH(
8499 "------------------ Framepack Format ----------\n"
8500 " id: %lu \n"
8501 " cancel_flag: %lu \n"
8502 " type: %lu \n"
8503 " quincunx_sampling_flagFormat: %lu \n"
8504 " content_interpretation_type: %lu \n"
8505 " content_interpretation_type: %lu \n"
8506 " spatial_flipping_flag: %lu \n"
8507 " frame0_flipped_flag: %lu \n"
8508 " field_views_flag: %lu \n"
8509 " current_frame_is_frame0_flag: %lu \n"
8510 " frame0_self_contained_flag: %lu \n"
8511 " frame1_self_contained_flag: %lu \n"
8512 " frame0_grid_position_x: %lu \n"
8513 " frame0_grid_position_y: %lu \n"
8514 " frame1_grid_position_x: %lu \n"
8515 " frame1_grid_position_y: %lu \n"
8516 " reserved_byte: %lu \n"
8517 " repetition_period: %lu \n"
8518 " extension_flag: %lu \n"
8519 "================== End of Framepack ===========",
8520 framepack->id,
8521 framepack->cancel_flag,
8522 framepack->type,
8523 framepack->quincunx_sampling_flag,
8524 framepack->content_interpretation_type,
8525 framepack->spatial_flipping_flag,
8526 framepack->frame0_flipped_flag,
8527 framepack->field_views_flag,
8528 framepack->current_frame_is_frame0_flag,
8529 framepack->frame0_self_contained_flag,
8530 framepack->frame1_self_contained_flag,
8531 framepack->frame0_grid_position_x,
8532 framepack->frame0_grid_position_y,
8533 framepack->frame1_grid_position_x,
8534 framepack->frame1_grid_position_y,
8535 framepack->reserved_byte,
8536 framepack->repetition_period,
8537 framepack->extension_flag);
Arun Menon906de572013-06-18 17:01:40 -07008538 } else if (extra->eType == OMX_ExtraDataNone) {
8539 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8540 } else {
8541 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008542 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008543}
8544
8545void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008546 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008547{
Arun Menon906de572013-06-18 17:01:40 -07008548 OMX_STREAMINTERLACEFORMAT *interlace_format;
8549 OMX_U32 mbaff = 0;
8550 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8551 return;
8552 }
8553 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8554 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8555 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8556 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8557 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8558 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8559 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8560 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8561 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8562 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8563 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8564 interlace_format->bInterlaceFormat = OMX_FALSE;
8565 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8566 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008567 } else if ((interlaced_format_type == INTERLACE_FRAME_TOPFIELDFIRST) && !mbaff) {
8568 interlace_format->bInterlaceFormat = OMX_TRUE;
8569 interlace_format->nInterlaceFormats = OMX_InterlaceFrameTopFieldFirst;
8570 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8571 } else if ((interlaced_format_type == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8572 interlace_format->bInterlaceFormat = OMX_TRUE;
8573 interlace_format->nInterlaceFormats = OMX_InterlaceFrameBottomFieldFirst;
8574 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07008575 } else {
8576 interlace_format->bInterlaceFormat = OMX_TRUE;
8577 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8578 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8579 }
8580 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008581}
8582
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008583void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008584 struct vdec_aspectratioinfo *aspect_ratio_info,
8585 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008586{
Arun Menon906de572013-06-18 17:01:40 -07008587 m_extradata = frame_info;
8588 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8589 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308590 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008591 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008592}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008593
8594void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008595 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308596 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008597 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008598{
Arun Menon906de572013-06-18 17:01:40 -07008599 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8600 struct msm_vidc_panscan_window *panscan_window;
8601 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008602 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008603 }
Arun Menon906de572013-06-18 17:01:40 -07008604 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8605 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8606 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8607 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8608 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8609 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8610 switch (picture_type) {
8611 case PICTURE_TYPE_I:
8612 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8613 break;
8614 case PICTURE_TYPE_P:
8615 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8616 break;
8617 case PICTURE_TYPE_B:
8618 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8619 break;
8620 default:
8621 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8622 }
8623 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8624 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8625 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8626 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8627 else
8628 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8629 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8630 frame_info->nConcealedMacroblocks = num_conceal_mb;
8631 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308632 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008633 frame_info->panScan.numWindows = 0;
8634 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8635 if (m_disp_hor_size && m_disp_vert_size) {
8636 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8637 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8638 }
8639 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008640
Arun Menon906de572013-06-18 17:01:40 -07008641 if (panscan_payload) {
8642 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8643 panscan_window = &panscan_payload->wnd[0];
8644 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8645 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8646 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8647 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8648 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8649 panscan_window++;
8650 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008651 }
Arun Menon906de572013-06-18 17:01:40 -07008652 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8653 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008654}
8655
8656void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8657{
Arun Menon906de572013-06-18 17:01:40 -07008658 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8659 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8660 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8661 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8662 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8663 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8664 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8665 *portDefn = m_port_def;
8666 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008667 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07008668 portDefn->format.video.nFrameWidth,
8669 portDefn->format.video.nStride,
8670 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008671}
8672
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308673void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8674 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
8675{
8676 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
8677 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
8678 DEBUG_PRINT_ERROR("frame packing size mismatch");
8679 return;
8680 }
8681 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
8682 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8683 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8684 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
8685 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8686 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8687 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8688 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
8689 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8690 memcpy(&framepack->id, s3d_frame_packing_payload,
8691 sizeof(struct msm_vidc_s3d_frame_packing_payload));
8692 memcpy(&m_frame_pack_arrangement, framepack,
8693 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
8694 print_debug_extradata(extra);
8695}
8696
Shalaj Jain273b3e02012-06-22 19:08:03 -07008697void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8698{
Arun Menon906de572013-06-18 17:01:40 -07008699 if (!client_extradata) {
8700 return;
8701 }
8702 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8703 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8704 extra->eType = OMX_ExtraDataNone;
8705 extra->nDataSize = 0;
8706 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008707
Arun Menon906de572013-06-18 17:01:40 -07008708 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008709}
8710
8711OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8712{
Arun Menon906de572013-06-18 17:01:40 -07008713 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8714 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008715 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07008716 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008717 }
Arun Menon906de572013-06-18 17:01:40 -07008718 if (m_desc_buffer_ptr == NULL) {
8719 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8720 calloc( (sizeof(desc_buffer_hdr)),
8721 drv_ctx.ip_buf.actualcount);
8722 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008723 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008724 return OMX_ErrorInsufficientResources;
8725 }
8726 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008727
Arun Menon906de572013-06-18 17:01:40 -07008728 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8729 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008730 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008731 return OMX_ErrorInsufficientResources;
8732 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008733
Arun Menon906de572013-06-18 17:01:40 -07008734 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008735}
8736
8737void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8738{
Arun Menon906de572013-06-18 17:01:40 -07008739 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8740 if (m_demux_entries < 8192) {
8741 m_demux_offsets[m_demux_entries++] = address_offset;
8742 }
8743 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008744}
8745
8746void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8747{
Arun Menon906de572013-06-18 17:01:40 -07008748 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8749 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8750 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008751
Arun Menon906de572013-06-18 17:01:40 -07008752 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008753
Arun Menon906de572013-06-18 17:01:40 -07008754 while (index < bytes_to_parse) {
8755 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8756 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8757 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8758 (buf[index+2] == 0x01)) ) {
8759 //Found start code, insert address offset
8760 insert_demux_addr_offset(index);
8761 if (buf[index+2] == 0x01) // 3 byte start code
8762 index += 3;
8763 else //4 byte start code
8764 index += 4;
8765 } else
8766 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008767 }
Arun Menon906de572013-06-18 17:01:40 -07008768 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8769 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008770}
8771
8772OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8773{
Arun Menon906de572013-06-18 17:01:40 -07008774 //fix this, handle 3 byte start code, vc1 terminator entry
8775 OMX_U8 *p_demux_data = NULL;
8776 OMX_U32 desc_data = 0;
8777 OMX_U32 start_addr = 0;
8778 OMX_U32 nal_size = 0;
8779 OMX_U32 suffix_byte = 0;
8780 OMX_U32 demux_index = 0;
8781 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008782
Arun Menon906de572013-06-18 17:01:40 -07008783 if (m_desc_buffer_ptr == NULL) {
8784 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8785 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008786 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008787
Arun Menon906de572013-06-18 17:01:40 -07008788 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8789 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8790 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8791 return OMX_ErrorBadParameter;
8792 }
8793
8794 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8795
8796 if ( ((OMX_U8*)p_demux_data == NULL) ||
8797 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8798 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8799 return OMX_ErrorBadParameter;
8800 } else {
8801 for (; demux_index < m_demux_entries; demux_index++) {
8802 desc_data = 0;
8803 start_addr = m_demux_offsets[demux_index];
8804 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8805 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8806 } else {
8807 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8808 }
8809 if (demux_index < (m_demux_entries - 1)) {
8810 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8811 } else {
8812 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8813 }
8814 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8815 (void *)start_addr,
8816 suffix_byte,
8817 nal_size,
8818 demux_index);
8819 desc_data = (start_addr >> 3) << 1;
8820 desc_data |= (start_addr & 7) << 21;
8821 desc_data |= suffix_byte << 24;
8822
8823 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8824 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8825 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8826 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8827
8828 p_demux_data += 16;
8829 }
8830 if (codec_type_parse == CODEC_TYPE_VC1) {
8831 DEBUG_PRINT_LOW("VC1 terminator entry");
8832 desc_data = 0;
8833 desc_data = 0x82 << 24;
8834 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8835 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8836 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8837 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8838 p_demux_data += 16;
8839 m_demux_entries++;
8840 }
8841 //Add zero word to indicate end of descriptors
8842 memset(p_demux_data, 0, sizeof(OMX_U32));
8843
8844 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8845 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8846 }
8847 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8848 m_demux_entries = 0;
8849 DEBUG_PRINT_LOW("Demux table complete!");
8850 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008851}
8852
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008853OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008854{
Arun Menon906de572013-06-18 17:01:40 -07008855 OMX_ERRORTYPE err = OMX_ErrorNone;
8856 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8857 if (iDivXDrmDecrypt) {
8858 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8859 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008860 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008861 delete iDivXDrmDecrypt;
8862 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008863 }
8864 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008865 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07008866 err = OMX_ErrorUndefined;
8867 }
8868 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008869}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008870
Vinay Kaliada4f4422013-01-09 10:45:03 -08008871omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8872{
Arun Menon906de572013-06-18 17:01:40 -07008873 enabled = false;
8874 omx = NULL;
8875 init_members();
8876 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008877}
8878
8879void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8880{
Arun Menon906de572013-06-18 17:01:40 -07008881 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008882}
8883
Arun Menon906de572013-06-18 17:01:40 -07008884void omx_vdec::allocate_color_convert_buf::init_members()
8885{
8886 allocated_count = 0;
8887 buffer_size_req = 0;
8888 buffer_alignment_req = 0;
8889 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8890 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8891 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8892 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008893#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008894 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008895#endif
Arun Menon906de572013-06-18 17:01:40 -07008896 for (int i = 0; i < MAX_COUNT; i++)
8897 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008898}
8899
Arun Menon906de572013-06-18 17:01:40 -07008900omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8901{
8902 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008903}
8904
8905bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8906{
Arun Menon906de572013-06-18 17:01:40 -07008907 bool status = true;
8908 unsigned int src_size = 0, destination_size = 0;
8909 OMX_COLOR_FORMATTYPE drv_color_format;
8910 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008911 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07008912 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008913 }
Arun Menon906de572013-06-18 17:01:40 -07008914 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008915 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07008916 return status;
8917 }
8918 pthread_mutex_lock(&omx->c_lock);
8919 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8920 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008921 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07008922 status = false;
8923 goto fail_update_buf_req;
8924 }
8925 c2d.close();
8926 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8927 omx->drv_ctx.video_resolution.frame_width,
8928 NV12_128m,YCbCr420P);
8929 if (status) {
8930 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8931 if (status)
8932 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8933 }
8934 if (status) {
8935 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8936 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008937 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07008938 "driver size %d destination size %d",
8939 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8940 status = false;
8941 c2d.close();
8942 buffer_size_req = 0;
8943 } else {
8944 buffer_size_req = destination_size;
8945 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8946 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8947 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8948 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8949 }
8950 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008951fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008952 pthread_mutex_unlock(&omx->c_lock);
8953 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008954}
8955
8956bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008957 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008958{
Arun Menon906de572013-06-18 17:01:40 -07008959 bool status = true;
8960 OMX_COLOR_FORMATTYPE drv_color_format;
8961 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008962 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07008963 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008964 }
Arun Menon906de572013-06-18 17:01:40 -07008965 pthread_mutex_lock(&omx->c_lock);
8966 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8967 drv_color_format = (OMX_COLOR_FORMATTYPE)
8968 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8969 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008970 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07008971 status = false;
8972 }
8973 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008974 DEBUG_PRINT_LOW("Enabling C2D");
Arun Menon906de572013-06-18 17:01:40 -07008975 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008976 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07008977 status = false;
8978 } else {
8979 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8980 if (enabled)
8981 c2d.destroy();
8982 enabled = false;
8983 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008984 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07008985 status = false;
8986 } else
8987 enabled = true;
8988 }
8989 } else {
8990 if (enabled)
8991 c2d.destroy();
8992 enabled = false;
8993 }
8994 pthread_mutex_unlock(&omx->c_lock);
8995 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008996}
8997
8998OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8999{
Arun Menon906de572013-06-18 17:01:40 -07009000 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009001 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009002 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009003 }
Arun Menon906de572013-06-18 17:01:40 -07009004 if (!enabled)
9005 return omx->m_out_mem_ptr;
9006 return m_out_mem_ptr_client;
9007}
9008
9009 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9010(OMX_BUFFERHEADERTYPE *bufadd)
9011{
9012 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009013 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009014 return NULL;
9015 }
9016 if (!enabled)
9017 return bufadd;
9018
9019 unsigned index = 0;
9020 index = bufadd - omx->m_out_mem_ptr;
9021 if (index < omx->drv_ctx.op_buf.actualcount) {
9022 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9023 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9024 bool status;
9025 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
9026 pthread_mutex_lock(&omx->c_lock);
9027 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9028 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
9029 pmem_baseaddress[index], pmem_baseaddress[index]);
9030 pthread_mutex_unlock(&omx->c_lock);
9031 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9032 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009033 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07009034 m_out_mem_ptr_client[index].nFilledLen = 0;
9035 return &m_out_mem_ptr_client[index];
9036 }
9037 } else
9038 m_out_mem_ptr_client[index].nFilledLen = 0;
9039 return &m_out_mem_ptr_client[index];
9040 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009041 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009042 return NULL;
9043}
9044
9045 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9046(OMX_BUFFERHEADERTYPE *bufadd)
9047{
9048 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009049 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009050 return NULL;
9051 }
9052 if (!enabled)
9053 return bufadd;
9054 unsigned index = 0;
9055 index = bufadd - m_out_mem_ptr_client;
9056 if (index < omx->drv_ctx.op_buf.actualcount) {
9057 return &omx->m_out_mem_ptr[index];
9058 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009059 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009060 return NULL;
9061}
9062 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9063(unsigned int &buffer_size)
9064{
9065 bool status = true;
9066 pthread_mutex_lock(&omx->c_lock);
9067 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009068 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009069 else {
9070 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009071 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009072 status = false;
9073 goto fail_get_buffer_size;
9074 }
9075 }
9076 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9077 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9078 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9079 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009080fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009081 pthread_mutex_unlock(&omx->c_lock);
9082 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009083}
9084OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009085 OMX_BUFFERHEADERTYPE *bufhdr)
9086{
9087 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009088
Arun Menon906de572013-06-18 17:01:40 -07009089 if (!enabled)
9090 return omx->free_output_buffer(bufhdr);
9091 if (enabled && omx->is_component_secure())
9092 return OMX_ErrorNone;
9093 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009094 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009095 return OMX_ErrorBadParameter;
9096 }
9097 index = bufhdr - m_out_mem_ptr_client;
9098 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009099 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009100 return OMX_ErrorBadParameter;
9101 }
9102 if (pmem_fd[index] > 0) {
9103 munmap(pmem_baseaddress[index], buffer_size_req);
9104 close(pmem_fd[index]);
9105 }
9106 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009107#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009108 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009109#endif
Arun Menon906de572013-06-18 17:01:40 -07009110 m_heap_ptr[index].video_heap_ptr = NULL;
9111 if (allocated_count > 0)
9112 allocated_count--;
9113 else
9114 allocated_count = 0;
9115 if (!allocated_count) {
9116 pthread_mutex_lock(&omx->c_lock);
9117 c2d.close();
9118 init_members();
9119 pthread_mutex_unlock(&omx->c_lock);
9120 }
9121 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009122}
9123
9124OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009125 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009126{
Arun Menon906de572013-06-18 17:01:40 -07009127 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9128 if (!enabled) {
9129 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9130 return eRet;
9131 }
9132 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009133 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009134 omx->is_component_secure());
9135 return OMX_ErrorUnsupportedSetting;
9136 }
9137 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009138 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9139 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009140 buffer_size_req,bytes);
9141 return OMX_ErrorBadParameter;
9142 }
9143 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009144 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009145 return OMX_ErrorInsufficientResources;
9146 }
9147 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9148 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9149 port,appData,omx->drv_ctx.op_buf.buffer_size);
9150 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009151 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009152 return eRet;
9153 }
9154 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309155 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009156 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009157 (temp_bufferHdr - omx->m_out_mem_ptr));
9158 return OMX_ErrorUndefined;
9159 }
9160 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009161#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009162 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9163 buffer_size_req,buffer_alignment_req,
9164 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9165 0);
9166 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9167 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009168 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009169 return OMX_ErrorInsufficientResources;
9170 }
9171 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9172 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009173
Arun Menon906de572013-06-18 17:01:40 -07009174 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009175 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009176 close(pmem_fd[i]);
9177 omx->free_ion_memory(&op_buf_ion_info[i]);
9178 return OMX_ErrorInsufficientResources;
9179 }
9180 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9181 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9182 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009183#endif
Arun Menon906de572013-06-18 17:01:40 -07009184 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9185 m_pmem_info_client[i].offset = 0;
9186 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9187 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9188 m_platform_list_client[i].nEntries = 1;
9189 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9190 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9191 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9192 m_out_mem_ptr_client[i].nFilledLen = 0;
9193 m_out_mem_ptr_client[i].nFlags = 0;
9194 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9195 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9196 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9197 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9198 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9199 m_out_mem_ptr_client[i].pAppPrivate = appData;
9200 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009201 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009202 allocated_count++;
9203 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009204}
9205
9206bool omx_vdec::is_component_secure()
9207{
Arun Menon906de572013-06-18 17:01:40 -07009208 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009209}
9210
9211bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9212{
Arun Menon906de572013-06-18 17:01:40 -07009213 bool status = true;
9214 if (!enabled) {
9215 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9216 dest_color_format = (OMX_COLOR_FORMATTYPE)
9217 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9218 else
9219 status = false;
9220 } else {
9221 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9222 status = false;
9223 } else
9224 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9225 }
9226 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009227}
Arun Menonbdb80b02013-08-12 17:45:54 -07009228
Arun Menonbdb80b02013-08-12 17:45:54 -07009229void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9230{
9231 int i = 0;
9232 bool buf_present = false;
9233 pthread_mutex_lock(&m_lock);
9234 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9235 //check the buffer fd, offset, uv addr with list contents
9236 //If present increment reference.
9237 if ((out_dynamic_list[i].fd == fd) &&
9238 (out_dynamic_list[i].offset == offset)) {
9239 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009240 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009241 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9242 buf_present = true;
9243 break;
9244 }
9245 }
9246 if (!buf_present) {
9247 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9248 //search for a entry to insert details of the new buffer
9249 if (out_dynamic_list[i].dup_fd == 0) {
9250 out_dynamic_list[i].fd = fd;
9251 out_dynamic_list[i].offset = offset;
9252 out_dynamic_list[i].dup_fd = dup(fd);
9253 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009254 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009255 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9256 break;
9257 }
9258 }
9259 }
9260 pthread_mutex_unlock(&m_lock);
9261}
9262
9263void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9264{
9265 int i = 0;
9266 pthread_mutex_lock(&m_lock);
9267 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9268 //check the buffer fd, offset, uv addr with list contents
9269 //If present decrement reference.
9270 if ((out_dynamic_list[i].fd == fd) &&
9271 (out_dynamic_list[i].offset == offset)) {
9272 out_dynamic_list[i].ref_count--;
9273 if (out_dynamic_list[i].ref_count == 0) {
9274 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009275 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009276 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9277 out_dynamic_list[i].dup_fd = 0;
9278 out_dynamic_list[i].fd = 0;
9279 out_dynamic_list[i].offset = 0;
9280 }
9281 break;
9282 }
9283 }
9284 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009285 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009286 }
9287 pthread_mutex_unlock(&m_lock);
9288}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009289
9290#ifdef _MSM8974_
9291void omx_vdec::send_codec_config() {
9292 if (codec_config_flag) {
9293 unsigned p1 = 0; // Parameter - 1
9294 unsigned p2 = 0; // Parameter - 2
9295 unsigned ident = 0;
9296 pthread_mutex_lock(&m_lock);
9297 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9298 while (m_etb_q.m_size) {
9299 m_etb_q.pop_entry(&p1,&p2,&ident);
9300 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9301 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9302 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9303 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9304 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9305 omx_report_error();
9306 }
9307 } else {
9308 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9309 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9310 }
9311 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9312 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9313 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9314 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9315 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9316 omx_report_error ();
9317 }
9318 } else {
9319 pending_input_buffers++;
9320 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9321 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9322 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9323 }
9324 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9325 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9326 (OMX_BUFFERHEADERTYPE *)p1);
9327 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9328 }
9329 }
9330 pthread_mutex_unlock(&m_lock);
9331 }
9332}
9333#endif