blob: 82fc260b8057154ad4040e5c3563557cb4f08816 [file] [log] [blame]
Shalaj Jain273b3e02012-06-22 19:08:03 -07001/*--------------------------------------------------------------------------
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -08002Copyright (c) 2010 - 2013, 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)
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700127
128int debug_level = PRIO_ERROR;
129
Praveen Chavancf924182013-12-06 23:16:23 -0800130static const OMX_U32 kMaxSmoothStreamingWidth = 1920;
131static const OMX_U32 kMaxSmoothStreamingHeight = 1088;
132
Shalaj Jain273b3e02012-06-22 19:08:03 -0700133void* async_message_thread (void *input)
134{
Arun Menon906de572013-06-18 17:01:40 -0700135 OMX_BUFFERHEADERTYPE *buffer;
136 struct v4l2_plane plane[VIDEO_MAX_PLANES];
137 struct pollfd pfd;
138 struct v4l2_buffer v4l2_buf;
139 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
140 struct v4l2_event dqevent;
141 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
142 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
143 pfd.fd = omx->drv_ctx.video_driver_fd;
144 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700145 DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
Arun Menon906de572013-06-18 17:01:40 -0700146 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
147 while (1) {
148 rc = poll(&pfd, 1, POLL_TIMEOUT);
149 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700150 DEBUG_PRINT_ERROR("Poll timedout");
Arun Menon906de572013-06-18 17:01:40 -0700151 break;
152 } else if (rc < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700153 DEBUG_PRINT_ERROR("Error while polling: %d", rc);
Arun Menon906de572013-06-18 17:01:40 -0700154 break;
155 }
156 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
157 struct vdec_msginfo vdec_msg;
158 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
159 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
160 v4l2_buf.length = omx->drv_ctx.num_planes;
161 v4l2_buf.m.planes = plane;
162 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
163 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
164 vdec_msg.status_code=VDEC_S_SUCCESS;
165 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
166 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
167 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
168 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
169 (uint64_t)v4l2_buf.timestamp.tv_usec;
170 if (vdec_msg.msgdata.output_frame.len) {
171 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
172 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
173 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
174 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
175 }
176 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700177 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700178 break;
179 }
180 }
181 }
182 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
183 struct vdec_msginfo vdec_msg;
184 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
185 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
186 v4l2_buf.length = 1;
187 v4l2_buf.m.planes = plane;
188 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
189 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
190 vdec_msg.status_code=VDEC_S_SUCCESS;
191 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
192 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700193 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700194 break;
195 }
196 }
197 }
198 if (pfd.revents & POLLPRI) {
199 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
200 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
201 struct vdec_msginfo vdec_msg;
202 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
203 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700204 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved insufficient");
Arun Menon906de572013-06-18 17:01:40 -0700205 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700206 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700207 break;
208 }
209 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
210 struct vdec_msginfo vdec_msg;
211 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
212 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700213 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700214 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700215 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700216 break;
217 }
218 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
219 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700220 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700221 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700222 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700223 break;
224 }
225 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700226 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700227 break;
228 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
229 struct vdec_msginfo vdec_msg;
230 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
231 vdec_msg.status_code=VDEC_S_SUCCESS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700232 DEBUG_PRINT_HIGH("SYS Error Recieved");
Arun Menon906de572013-06-18 17:01:40 -0700233 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700234 DEBUG_PRINT_HIGH("async_message_thread Exited");
Arun Menon906de572013-06-18 17:01:40 -0700235 break;
236 }
Arun Menon45346052013-11-13 12:40:08 -0800237 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
Arun Menonbdb80b02013-08-12 17:45:54 -0700238 unsigned int *ptr = (unsigned int *)dqevent.u.data;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700239 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700240 omx->buf_ref_remove(ptr[0], ptr[1]);
241 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
242 unsigned int *ptr = (unsigned int *)dqevent.u.data;
243 struct vdec_msginfo vdec_msg;
244
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700245 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
Arun Menonbdb80b02013-08-12 17:45:54 -0700246
247 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
248 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
249 v4l2_buf.length = omx->drv_ctx.num_planes;
250 v4l2_buf.m.planes = plane;
251 v4l2_buf.index = ptr[5];
252 v4l2_buf.flags = 0;
253
254 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
255 vdec_msg.status_code = VDEC_S_SUCCESS;
256 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
257 vdec_msg.msgdata.output_frame.len = 0;
258 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
259 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
260 (uint64_t)ptr[4];
261 if (omx->async_message_process(input,&vdec_msg) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700262 DEBUG_PRINT_HIGH("async_message_thread Exitedn");
Arun Menonbdb80b02013-08-12 17:45:54 -0700263 break;
264 }
265 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700266 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700267 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
Arun Menon906de572013-06-18 17:01:40 -0700268 continue;
269 }
270 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700271 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700272 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700273 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700274}
275
276void* message_thread(void *input)
277{
Arun Menon906de572013-06-18 17:01:40 -0700278 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
279 unsigned char id;
280 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700281
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700282 DEBUG_PRINT_HIGH("omx_vdec: message thread start");
Arun Menon906de572013-06-18 17:01:40 -0700283 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
284 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700285
Arun Menon906de572013-06-18 17:01:40 -0700286 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700287
Arun Menon906de572013-06-18 17:01:40 -0700288 if (0 == n) {
289 break;
290 }
291
292 if (1 == n) {
293 omx->process_event_cb(omx, id);
294 }
295 if ((n < 0) && (errno != EINTR)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700296 DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
Arun Menon906de572013-06-18 17:01:40 -0700297 break;
298 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700299 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700300 DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
Arun Menon906de572013-06-18 17:01:40 -0700301 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700302}
303
304void post_message(omx_vdec *omx, unsigned char id)
305{
Arun Menon906de572013-06-18 17:01:40 -0700306 int ret_value;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700307 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
Arun Menon906de572013-06-18 17:01:40 -0700308 ret_value = write(omx->m_pipe_out, &id, 1);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700309 DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700310}
311
312// omx_cmd_queue destructor
313omx_vdec::omx_cmd_queue::~omx_cmd_queue()
314{
Arun Menon906de572013-06-18 17:01:40 -0700315 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700316}
317
318// omx cmd queue constructor
319omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
320{
321 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
322}
323
324// omx cmd queue insert
325bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
326{
Arun Menon906de572013-06-18 17:01:40 -0700327 bool ret = true;
328 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
329 m_q[m_write].id = id;
330 m_q[m_write].param1 = p1;
331 m_q[m_write].param2 = p2;
332 m_write++;
333 m_size ++;
334 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
335 m_write = 0;
336 }
337 } else {
338 ret = false;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700339 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700340 }
Arun Menon906de572013-06-18 17:01:40 -0700341 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700342}
343
344// omx cmd queue pop
345bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
346{
Arun Menon906de572013-06-18 17:01:40 -0700347 bool ret = true;
348 if (m_size > 0) {
349 *id = m_q[m_read].id;
350 *p1 = m_q[m_read].param1;
351 *p2 = m_q[m_read].param2;
352 // Move the read pointer ahead
353 ++m_read;
354 --m_size;
355 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
356 m_read = 0;
357 }
358 } else {
359 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700360 }
Arun Menon906de572013-06-18 17:01:40 -0700361 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700362}
363
364// Retrieve the first mesg type in the queue
365unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
366{
367 return m_q[m_read].id;
368}
369
370#ifdef _ANDROID_
371omx_vdec::ts_arr_list::ts_arr_list()
372{
Arun Menon906de572013-06-18 17:01:40 -0700373 //initialize timestamps array
374 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700375}
376omx_vdec::ts_arr_list::~ts_arr_list()
377{
Arun Menon906de572013-06-18 17:01:40 -0700378 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700379}
380
381bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
382{
Arun Menon906de572013-06-18 17:01:40 -0700383 bool ret = true;
384 bool duplicate_ts = false;
385 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700386
Arun Menon906de572013-06-18 17:01:40 -0700387 //insert at the first available empty location
388 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
389 if (!m_ts_arr_list[idx].valid) {
390 //found invalid or empty entry, save timestamp
391 m_ts_arr_list[idx].valid = true;
392 m_ts_arr_list[idx].timestamp = ts;
393 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
394 ts, idx);
395 break;
396 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700397 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700398
Arun Menon906de572013-06-18 17:01:40 -0700399 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
400 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
401 ret = false;
402 }
403 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700404}
405
406bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
407{
Arun Menon906de572013-06-18 17:01:40 -0700408 bool ret = true;
409 int min_idx = -1;
410 OMX_TICKS min_ts = 0;
411 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700412
Arun Menon906de572013-06-18 17:01:40 -0700413 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700414
Arun Menon906de572013-06-18 17:01:40 -0700415 if (m_ts_arr_list[idx].valid) {
416 //found valid entry, save index
417 if (min_idx < 0) {
418 //first valid entry
419 min_ts = m_ts_arr_list[idx].timestamp;
420 min_idx = idx;
421 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
422 min_ts = m_ts_arr_list[idx].timestamp;
423 min_idx = idx;
424 }
425 }
426
Shalaj Jain273b3e02012-06-22 19:08:03 -0700427 }
428
Arun Menon906de572013-06-18 17:01:40 -0700429 if (min_idx < 0) {
430 //no valid entries found
431 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
432 ts = 0;
433 ret = false;
434 } else {
435 ts = m_ts_arr_list[min_idx].timestamp;
436 m_ts_arr_list[min_idx].valid = false;
437 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
438 ts, min_idx);
439 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700440
Arun Menon906de572013-06-18 17:01:40 -0700441 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700442
443}
444
445
446bool omx_vdec::ts_arr_list::reset_ts_list()
447{
Arun Menon906de572013-06-18 17:01:40 -0700448 bool ret = true;
449 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700450
Arun Menon906de572013-06-18 17:01:40 -0700451 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
452 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
453 m_ts_arr_list[idx].valid = false;
454 }
455 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700456}
457#endif
458
459// factory function executed by the core to create instances
460void *get_omx_component_factory_fn(void)
461{
Arun Menon906de572013-06-18 17:01:40 -0700462 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700463}
464
465#ifdef _ANDROID_
466#ifdef USE_ION
467VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700468 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700469{
Arun Menon906de572013-06-18 17:01:40 -0700470 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700471}
472#else
473VideoHeap::VideoHeap(int fd, size_t size, void* base)
474{
475 // dup file descriptor, map once, use pmem
476 init(dup(fd), base, size, 0 , MEM_DEVICE);
477}
478#endif
479#endif // _ANDROID_
480/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700481 FUNCTION
482 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700483
Arun Menon906de572013-06-18 17:01:40 -0700484 DESCRIPTION
485 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700486
Arun Menon906de572013-06-18 17:01:40 -0700487 PARAMETERS
488 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700489
Arun Menon906de572013-06-18 17:01:40 -0700490 RETURN VALUE
491 None.
492 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800493omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700494 m_state(OMX_StateInvalid),
495 m_app_data(NULL),
496 m_inp_mem_ptr(NULL),
497 m_out_mem_ptr(NULL),
498 m_inp_err_count(0),
499 input_flush_progress (false),
500 output_flush_progress (false),
501 input_use_buffer (false),
502 output_use_buffer (false),
503 ouput_egl_buffers(false),
504 m_use_output_pmem(OMX_FALSE),
505 m_out_mem_region_smi(OMX_FALSE),
506 m_out_pvt_entry_pmem(OMX_FALSE),
507 pending_input_buffers(0),
508 pending_output_buffers(0),
509 m_out_bm_count(0),
510 m_inp_bm_count(0),
511 m_inp_bPopulated(OMX_FALSE),
512 m_out_bPopulated(OMX_FALSE),
513 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700514#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700515 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700516#endif
Arun Menon906de572013-06-18 17:01:40 -0700517 m_inp_bEnabled(OMX_TRUE),
518 m_out_bEnabled(OMX_TRUE),
519 m_in_alloc_cnt(0),
520 m_platform_list(NULL),
521 m_platform_entry(NULL),
522 m_pmem_info(NULL),
523 arbitrary_bytes (true),
524 psource_frame (NULL),
525 pdest_frame (NULL),
526 m_inp_heap_ptr (NULL),
527 m_phdr_pmem_ptr(NULL),
528 m_heap_inp_bm_count (0),
529 codec_type_parse ((codec_type)0),
530 first_frame_meta (true),
531 frame_count (0),
532 nal_count (0),
533 nal_length(0),
534 look_ahead_nal (false),
535 first_frame(0),
536 first_buffer(NULL),
537 first_frame_size (0),
538 m_device_file_ptr(NULL),
539 m_vc1_profile((vc1_profile_type)0),
Arun Menon906de572013-06-18 17:01:40 -0700540 h264_last_au_ts(LLONG_MAX),
541 h264_last_au_flags(0),
Surajit Podderd2644d52013-08-28 17:59:06 +0530542 m_disp_hor_size(0),
543 m_disp_vert_size(0),
Arun Menon906de572013-06-18 17:01:40 -0700544 prev_ts(LLONG_MAX),
545 rst_prev_ts(true),
546 frm_int(0),
Arun Menon906de572013-06-18 17:01:40 -0700547 in_reconfig(false),
548 m_display_id(NULL),
549 h264_parser(NULL),
550 client_extradata(0),
551 m_reject_avc_1080p_mp (0),
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +0530552 m_other_extradata(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700553#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700554 m_enable_android_native_buffers(OMX_FALSE),
555 m_use_android_native_buffers(OMX_FALSE),
556 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700557#endif
Arun Menon906de572013-06-18 17:01:40 -0700558 m_desc_buffer_ptr(NULL),
559 secure_mode(false),
Surajit Podderd2644d52013-08-28 17:59:06 +0530560 m_profile(0),
Arun Menon906de572013-06-18 17:01:40 -0700561 client_set_fps(false)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700562{
Arun Menon906de572013-06-18 17:01:40 -0700563 /* Assumption is that , to begin with , we have all the frames with decoder */
564 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700565 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700566#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700567 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700568 property_get("vidc.debug.level", property_value, "0");
569 debug_level = atoi(property_value);
570 property_value[0] = '\0';
571
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700572 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
573
Arun Menon906de572013-06-18 17:01:40 -0700574 property_get("vidc.dec.debug.perf", property_value, "0");
575 perf_flag = atoi(property_value);
576 if (perf_flag) {
577 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
578 dec_time.start();
579 proc_frms = latency = 0;
580 }
581 prev_n_filled_len = 0;
582 property_value[0] = '\0';
583 property_get("vidc.dec.debug.ts", property_value, "0");
584 m_debug_timestamp = atoi(property_value);
585 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
586 if (m_debug_timestamp) {
587 time_stamp_dts.set_timestamp_reorder_mode(true);
588 time_stamp_dts.enable_debug_print(true);
589 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700590
Arun Menon906de572013-06-18 17:01:40 -0700591 property_value[0] = '\0';
592 property_get("vidc.dec.debug.concealedmb", property_value, "0");
593 m_debug_concealedmb = atoi(property_value);
594 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700595
Arun Menon906de572013-06-18 17:01:40 -0700596 property_value[0] = '\0';
597 property_get("vidc.dec.profile.check", property_value, "0");
598 m_reject_avc_1080p_mp = atoi(property_value);
599 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530600
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700601 property_value[0] = '\0';
602 property_get("vidc.dec.log.in", property_value, "0");
603 m_debug.in_buffer_log = atoi(property_value);
604
605 property_value[0] = '\0';
606 property_get("vidc.dec.log.out", property_value, "0");
607 m_debug.out_buffer_log = atoi(property_value);
608 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
609
610 property_value[0] = '\0';
611 property_get("vidc.log.loc", property_value, "");
612 if (*property_value)
613 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700614#endif
Arun Menon906de572013-06-18 17:01:40 -0700615 memset(&m_cmp,0,sizeof(m_cmp));
616 memset(&m_cb,0,sizeof(m_cb));
617 memset (&drv_ctx,0,sizeof(drv_ctx));
618 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
619 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
620 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
621 m_demux_entries = 0;
622 msg_thread_id = 0;
623 async_thread_id = 0;
624 msg_thread_created = false;
625 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700626#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700627 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700628#endif
Arun Menon906de572013-06-18 17:01:40 -0700629 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Maheshwar Ajjad2df2182013-10-24 19:20:34 +0530630 memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -0700631 drv_ctx.timestamp_adjust = false;
632 drv_ctx.video_driver_fd = -1;
633 m_vendor_config.pData = NULL;
634 pthread_mutex_init(&m_lock, NULL);
635 pthread_mutex_init(&c_lock, NULL);
636 sem_init(&m_cmd_lock,0,0);
637 streaming[CAPTURE_PORT] =
638 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700639#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700640 char extradata_value[PROPERTY_VALUE_MAX] = {0};
641 property_get("vidc.dec.debug.extradata", extradata_value, "0");
642 m_debug_extradata = atoi(extradata_value);
643 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700644#endif
Arun Menon906de572013-06-18 17:01:40 -0700645 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
646 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700647 dynamic_buf_mode = false;
648 out_dynamic_list = NULL;
Praveen Chavane78460c2013-12-06 23:16:04 -0800649 is_down_scalar_enabled = false;
Praveen Chavancf924182013-12-06 23:16:23 -0800650 m_smoothstreaming_mode = false;
651 m_smoothstreaming_width = 0;
652 m_smoothstreaming_height = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700653}
654
Vinay Kalia85793762012-06-14 19:12:34 -0700655static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700656 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
657 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
658 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700659 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
660 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
Arun Menon906de572013-06-18 17:01:40 -0700661 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
662 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700663};
664
665static OMX_ERRORTYPE subscribe_to_events(int fd)
666{
Arun Menon906de572013-06-18 17:01:40 -0700667 OMX_ERRORTYPE eRet = OMX_ErrorNone;
668 struct v4l2_event_subscription sub;
669 int array_sz = sizeof(event_type)/sizeof(int);
670 int i,rc;
671 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700672 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700673 return OMX_ErrorBadParameter;
674 }
Vinay Kalia85793762012-06-14 19:12:34 -0700675
Arun Menon906de572013-06-18 17:01:40 -0700676 for (i = 0; i < array_sz; ++i) {
677 memset(&sub, 0, sizeof(sub));
678 sub.type = event_type[i];
679 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
680 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700681 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700682 break;
683 }
684 }
685 if (i < array_sz) {
686 for (--i; i >=0 ; i--) {
687 memset(&sub, 0, sizeof(sub));
688 sub.type = event_type[i];
689 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
690 if (rc)
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700691 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700692 }
693 eRet = OMX_ErrorNotImplemented;
694 }
695 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700696}
697
698
699static OMX_ERRORTYPE unsubscribe_to_events(int fd)
700{
Arun Menon906de572013-06-18 17:01:40 -0700701 OMX_ERRORTYPE eRet = OMX_ErrorNone;
702 struct v4l2_event_subscription sub;
703 int array_sz = sizeof(event_type)/sizeof(int);
704 int i,rc;
705 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700706 DEBUG_PRINT_ERROR("Invalid input: %d", fd);
Arun Menon906de572013-06-18 17:01:40 -0700707 return OMX_ErrorBadParameter;
708 }
Vinay Kalia85793762012-06-14 19:12:34 -0700709
Arun Menon906de572013-06-18 17:01:40 -0700710 for (i = 0; i < array_sz; ++i) {
711 memset(&sub, 0, sizeof(sub));
712 sub.type = event_type[i];
713 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
714 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700715 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
Arun Menon906de572013-06-18 17:01:40 -0700716 break;
717 }
718 }
719 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700720}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700721
722/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700723 FUNCTION
724 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700725
Arun Menon906de572013-06-18 17:01:40 -0700726 DESCRIPTION
727 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700728
Arun Menon906de572013-06-18 17:01:40 -0700729 PARAMETERS
730 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700731
Arun Menon906de572013-06-18 17:01:40 -0700732 RETURN VALUE
733 None.
734 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700735omx_vdec::~omx_vdec()
736{
Arun Menon906de572013-06-18 17:01:40 -0700737 m_pmem_info = NULL;
738 struct v4l2_decoder_cmd dec;
739 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
740 if (m_pipe_in) close(m_pipe_in);
741 if (m_pipe_out) close(m_pipe_out);
742 m_pipe_in = -1;
743 m_pipe_out = -1;
744 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
745 if (msg_thread_created)
746 pthread_join(msg_thread_id,NULL);
747 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
748 dec.cmd = V4L2_DEC_CMD_STOP;
749 if (drv_ctx.video_driver_fd >=0 ) {
750 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700751 DEBUG_PRINT_ERROR("STOP Command failed");
Arun Menon906de572013-06-18 17:01:40 -0700752 }
753 if (async_thread_created)
754 pthread_join(async_thread_id,NULL);
755 unsubscribe_to_events(drv_ctx.video_driver_fd);
756 close(drv_ctx.video_driver_fd);
757 pthread_mutex_destroy(&m_lock);
758 pthread_mutex_destroy(&c_lock);
759 sem_destroy(&m_cmd_lock);
760 if (perf_flag) {
761 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
762 dec_time.end();
763 }
764 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700765}
766
Arun Menon906de572013-06-18 17:01:40 -0700767int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
768{
769 struct v4l2_requestbuffers bufreq;
770 int rc = 0;
771 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
772 bufreq.memory = V4L2_MEMORY_USERPTR;
773 bufreq.count = 0;
774 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
775 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530776 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
777 bufreq.memory = V4L2_MEMORY_USERPTR;
778 bufreq.count = 0;
779 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
780 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700781 }
782 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700783}
784
Shalaj Jain273b3e02012-06-22 19:08:03 -0700785/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700786 FUNCTION
787 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700788
Arun Menon906de572013-06-18 17:01:40 -0700789 DESCRIPTION
790 IL Client callbacks are generated through this routine. The decoder
791 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700792
Arun Menon906de572013-06-18 17:01:40 -0700793 PARAMETERS
794 ctxt -- Context information related to the self.
795 id -- Event identifier. This could be any of the following:
796 1. Command completion event
797 2. Buffer done callback event
798 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700799
Arun Menon906de572013-06-18 17:01:40 -0700800 RETURN VALUE
801 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700802
Arun Menon906de572013-06-18 17:01:40 -0700803 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700804void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
805{
Arun Menon906de572013-06-18 17:01:40 -0700806 signed p1; // Parameter - 1
807 signed p2; // Parameter - 2
808 unsigned ident;
809 unsigned qsize=0; // qsize
810 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700811
Arun Menon906de572013-06-18 17:01:40 -0700812 if (!pThis) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700813 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
Arun Menon906de572013-06-18 17:01:40 -0700814 __func__);
815 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700816 }
817
Arun Menon906de572013-06-18 17:01:40 -0700818 // Protect the shared queue data structure
819 do {
820 /*Read the message id's from the queue*/
821 pthread_mutex_lock(&pThis->m_lock);
822 qsize = pThis->m_cmd_q.m_size;
823 if (qsize) {
824 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700825 }
Arun Menon906de572013-06-18 17:01:40 -0700826
827 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
828 qsize = pThis->m_ftb_q.m_size;
829 if (qsize) {
830 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
831 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700832 }
Arun Menon906de572013-06-18 17:01:40 -0700833
834 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
835 qsize = pThis->m_etb_q.m_size;
836 if (qsize) {
837 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
838 }
839 }
840 pthread_mutex_unlock(&pThis->m_lock);
841
842 /*process message if we have one*/
843 if (qsize > 0) {
844 id = ident;
845 switch (id) {
846 case OMX_COMPONENT_GENERATE_EVENT:
847 if (pThis->m_cb.EventHandler) {
848 switch (p1) {
849 case OMX_CommandStateSet:
850 pThis->m_state = (OMX_STATETYPE) p2;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700851 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
Arun Menon906de572013-06-18 17:01:40 -0700852 pThis->m_state);
853 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
854 OMX_EventCmdComplete, p1, p2, NULL);
855 break;
856
857 case OMX_EventError:
858 if (p2 == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700859 DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
Arun Menon906de572013-06-18 17:01:40 -0700860 pThis->m_state = (OMX_STATETYPE) p2;
861 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
862 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
863 } else if (p2 == OMX_ErrorHardware) {
864 pThis->omx_report_error();
865 } else {
866 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
867 OMX_EventError, p2, (OMX_U32)NULL, NULL );
868 }
869 break;
870
871 case OMX_CommandPortDisable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700872 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700873 if (BITMASK_PRESENT(&pThis->m_flags,
874 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
875 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
876 break;
877 }
878 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
879 OMX_ERRORTYPE eRet = OMX_ErrorNone;
880 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
881 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700882 DEBUG_PRINT_HIGH("Failed to release output buffers");
Arun Menon906de572013-06-18 17:01:40 -0700883 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
884 pThis->in_reconfig = false;
885 if (eRet != OMX_ErrorNone) {
886 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
887 pThis->omx_report_error();
888 break;
889 }
890 }
891 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
892 OMX_EventCmdComplete, p1, p2, NULL );
893 break;
894 case OMX_CommandPortEnable:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700895 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
Arun Menon906de572013-06-18 17:01:40 -0700896 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
897 OMX_EventCmdComplete, p1, p2, NULL );
898 break;
899
900 default:
901 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
902 OMX_EventCmdComplete, p1, p2, NULL );
903 break;
904
905 }
906 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700907 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Arun Menon906de572013-06-18 17:01:40 -0700908 }
909 break;
910 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
911 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
912 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700913 DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
Arun Menon906de572013-06-18 17:01:40 -0700914 pThis->omx_report_error ();
915 }
916 break;
917 case OMX_COMPONENT_GENERATE_ETB:
918 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
919 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700920 DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700921 pThis->omx_report_error ();
922 }
923 break;
924
925 case OMX_COMPONENT_GENERATE_FTB:
926 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
927 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700928 DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
Arun Menon906de572013-06-18 17:01:40 -0700929 pThis->omx_report_error ();
930 }
931 break;
932
933 case OMX_COMPONENT_GENERATE_COMMAND:
934 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
935 (OMX_U32)p2,(OMX_PTR)NULL);
936 break;
937
938 case OMX_COMPONENT_GENERATE_EBD:
939
940 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700941 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700942 pThis->omx_report_error ();
943 } else {
944 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
945 pThis->m_inp_err_count++;
946 pThis->time_stamp_dts.remove_time_stamp(
947 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
948 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
949 ?true:false);
950 } else {
951 pThis->m_inp_err_count = 0;
952 }
953 if ( pThis->empty_buffer_done(&pThis->m_cmp,
954 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700955 DEBUG_PRINT_ERROR("empty_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700956 pThis->omx_report_error ();
957 }
958 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700959 DEBUG_PRINT_ERROR("Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
Arun Menon906de572013-06-18 17:01:40 -0700960 pThis->omx_report_error ();
961 }
962 }
963 break;
964 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
965 int64_t *timestamp = (int64_t *)p1;
966 if (p1) {
967 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
968 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
969 ?true:false);
970 free(timestamp);
971 }
972 }
973 break;
974 case OMX_COMPONENT_GENERATE_FBD:
975 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700976 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
Arun Menon906de572013-06-18 17:01:40 -0700977 pThis->omx_report_error ();
978 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
979 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700980 DEBUG_PRINT_ERROR("fill_buffer_done failure");
Arun Menon906de572013-06-18 17:01:40 -0700981 pThis->omx_report_error ();
982 }
983 break;
984
985 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700986 DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -0700987 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700988 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -0700989 } else {
990 pThis->execute_input_flush();
991 if (pThis->m_cb.EventHandler) {
992 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -0700993 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
Arun Menon906de572013-06-18 17:01:40 -0700994 pThis->omx_report_error ();
995 } else {
996 /*Check if we need generate event for Flush done*/
997 if (BITMASK_PRESENT(&pThis->m_flags,
998 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
999 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001000 DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
Arun Menon906de572013-06-18 17:01:40 -07001001 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1002 OMX_EventCmdComplete,OMX_CommandFlush,
1003 OMX_CORE_INPUT_PORT_INDEX,NULL );
1004 }
1005 if (BITMASK_PRESENT(&pThis->m_flags,
1006 OMX_COMPONENT_IDLE_PENDING)) {
1007 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001008 DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
Arun Menon906de572013-06-18 17:01:40 -07001009 pThis->omx_report_error ();
1010 } else {
1011 pThis->streaming[OUTPUT_PORT] = false;
1012 }
1013 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001014 DEBUG_PRINT_LOW("Input flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001015 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1016 OMX_COMPONENT_GENERATE_STOP_DONE);
1017 }
1018 }
1019 }
1020 } else {
1021 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1022 }
1023 }
1024 break;
1025
1026 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001027 DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
Arun Menon906de572013-06-18 17:01:40 -07001028 if (!pThis->output_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001029 DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
Arun Menon906de572013-06-18 17:01:40 -07001030 } else {
1031 pThis->execute_output_flush();
1032 if (pThis->m_cb.EventHandler) {
1033 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001034 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
Arun Menon906de572013-06-18 17:01:40 -07001035 pThis->omx_report_error ();
1036 } else {
1037 /*Check if we need generate event for Flush done*/
1038 if (BITMASK_PRESENT(&pThis->m_flags,
1039 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001040 DEBUG_PRINT_LOW("Notify Output Flush done");
Arun Menon906de572013-06-18 17:01:40 -07001041 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1042 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1043 OMX_EventCmdComplete,OMX_CommandFlush,
1044 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1045 }
1046 if (BITMASK_PRESENT(&pThis->m_flags,
1047 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001048 DEBUG_PRINT_LOW("Internal flush complete");
Arun Menon906de572013-06-18 17:01:40 -07001049 BITMASK_CLEAR (&pThis->m_flags,
1050 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1051 if (BITMASK_PRESENT(&pThis->m_flags,
1052 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1053 pThis->post_event(OMX_CommandPortDisable,
1054 OMX_CORE_OUTPUT_PORT_INDEX,
1055 OMX_COMPONENT_GENERATE_EVENT);
1056 BITMASK_CLEAR (&pThis->m_flags,
1057 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1058
1059 }
1060 }
1061
1062 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1063 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001064 DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
Arun Menon906de572013-06-18 17:01:40 -07001065 pThis->omx_report_error ();
1066 break;
1067 }
1068 pThis->streaming[CAPTURE_PORT] = false;
1069 if (!pThis->input_flush_progress) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001070 DEBUG_PRINT_LOW("Output flush done hence issue stop");
Arun Menon906de572013-06-18 17:01:40 -07001071 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1072 OMX_COMPONENT_GENERATE_STOP_DONE);
1073 }
1074 }
1075 }
1076 } else {
1077 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1078 }
1079 }
1080 break;
1081
1082 case OMX_COMPONENT_GENERATE_START_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001083 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001084
1085 if (pThis->m_cb.EventHandler) {
1086 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001087 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
Arun Menon906de572013-06-18 17:01:40 -07001088 pThis->omx_report_error ();
1089 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001090 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001091 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001092 DEBUG_PRINT_LOW("Move to executing");
Arun Menon906de572013-06-18 17:01:40 -07001093 // Send the callback now
1094 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1095 pThis->m_state = OMX_StateExecuting;
1096 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1097 OMX_EventCmdComplete,OMX_CommandStateSet,
1098 OMX_StateExecuting, NULL);
1099 } else if (BITMASK_PRESENT(&pThis->m_flags,
1100 OMX_COMPONENT_PAUSE_PENDING)) {
1101 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1102 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001103 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
Arun Menon906de572013-06-18 17:01:40 -07001104 pThis->omx_report_error ();
1105 }
1106 }
1107 }
1108 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001109 DEBUG_PRINT_LOW("Event Handler callback is NULL");
Arun Menon906de572013-06-18 17:01:40 -07001110 }
1111 break;
1112
1113 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001114 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001115 if (pThis->m_cb.EventHandler) {
1116 if (p2 != VDEC_S_SUCCESS) {
1117 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1118 pThis->omx_report_error ();
1119 } else {
1120 pThis->complete_pending_buffer_done_cbs();
1121 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001122 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
Arun Menon906de572013-06-18 17:01:40 -07001123 //Send the callback now
1124 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1125 pThis->m_state = OMX_StatePause;
1126 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1127 OMX_EventCmdComplete,OMX_CommandStateSet,
1128 OMX_StatePause, NULL);
1129 }
1130 }
1131 } else {
1132 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1133 }
1134
1135 break;
1136
1137 case OMX_COMPONENT_GENERATE_RESUME_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001138 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001139 if (pThis->m_cb.EventHandler) {
1140 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001141 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
Arun Menon906de572013-06-18 17:01:40 -07001142 pThis->omx_report_error ();
1143 } else {
1144 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001145 DEBUG_PRINT_LOW("Moving the decoder to execute state");
Arun Menon906de572013-06-18 17:01:40 -07001146 // Send the callback now
1147 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1148 pThis->m_state = OMX_StateExecuting;
1149 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1150 OMX_EventCmdComplete,OMX_CommandStateSet,
1151 OMX_StateExecuting,NULL);
1152 }
1153 }
1154 } else {
1155 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1156 }
1157
1158 break;
1159
1160 case OMX_COMPONENT_GENERATE_STOP_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001161 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001162 if (pThis->m_cb.EventHandler) {
1163 if (p2 != VDEC_S_SUCCESS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001164 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
Arun Menon906de572013-06-18 17:01:40 -07001165 pThis->omx_report_error ();
1166 } else {
1167 pThis->complete_pending_buffer_done_cbs();
1168 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001169 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
Arun Menon906de572013-06-18 17:01:40 -07001170 // Send the callback now
1171 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1172 pThis->m_state = OMX_StateIdle;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001173 DEBUG_PRINT_LOW("Move to Idle State");
Arun Menon906de572013-06-18 17:01:40 -07001174 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1175 OMX_EventCmdComplete,OMX_CommandStateSet,
1176 OMX_StateIdle,NULL);
1177 }
1178 }
1179 } else {
1180 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1181 }
1182
1183 break;
1184
1185 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001186 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Arun Menon906de572013-06-18 17:01:40 -07001187
1188 if (p2 == OMX_IndexParamPortDefinition) {
1189 pThis->in_reconfig = true;
1190 }
1191 if (pThis->m_cb.EventHandler) {
1192 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1193 OMX_EventPortSettingsChanged, p1, p2, NULL );
1194 } else {
1195 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1196 }
1197
Arun Menon906de572013-06-18 17:01:40 -07001198 break;
1199
1200 case OMX_COMPONENT_GENERATE_EOS_DONE:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001201 DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
Arun Menon906de572013-06-18 17:01:40 -07001202 if (pThis->m_cb.EventHandler) {
1203 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1204 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1205 } else {
1206 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1207 }
1208 pThis->prev_ts = LLONG_MAX;
1209 pThis->rst_prev_ts = true;
1210 break;
1211
1212 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001213 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
Arun Menon906de572013-06-18 17:01:40 -07001214 pThis->omx_report_error ();
1215 break;
1216
1217 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001218 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
Arun Menon906de572013-06-18 17:01:40 -07001219 pThis->omx_report_unsupported_setting();
1220 break;
1221
Arun Menon906de572013-06-18 17:01:40 -07001222 default:
1223 break;
1224 }
1225 }
1226 pthread_mutex_lock(&pThis->m_lock);
1227 qsize = pThis->m_cmd_q.m_size;
1228 if (pThis->m_state != OMX_StatePause)
1229 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1230 pthread_mutex_unlock(&pThis->m_lock);
1231 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001232
1233}
1234
Vinay Kaliab9e98102013-04-02 19:31:43 -07001235int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001236{
Arun Menon906de572013-06-18 17:01:40 -07001237 int format_changed = 0;
Surajit Podderd2644d52013-08-28 17:59:06 +05301238 if ((height != (int)drv_ctx.video_resolution.frame_height) ||
1239 (width != (int)drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001240 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
Arun Menon906de572013-06-18 17:01:40 -07001241 width, drv_ctx.video_resolution.frame_width,
1242 height,drv_ctx.video_resolution.frame_height);
1243 format_changed = 1;
1244 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001245 drv_ctx.video_resolution.frame_height = height;
1246 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001247 drv_ctx.video_resolution.scan_lines = scan_lines;
1248 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001249 rectangle.nLeft = 0;
1250 rectangle.nTop = 0;
1251 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1252 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Arun Menon906de572013-06-18 17:01:40 -07001253 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001254}
1255
Arun Menon6836ba02013-02-19 20:37:40 -08001256OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1257{
Arun Menon906de572013-06-18 17:01:40 -07001258 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1259 OMX_MAX_STRINGNAME_SIZE) &&
1260 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1261 m_decoder_capability.max_width = 1280;
1262 m_decoder_capability.max_height = 720;
1263 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1264 }
Arun Menon888aa852013-05-30 11:24:42 -07001265
Arun Menon906de572013-06-18 17:01:40 -07001266 if ((drv_ctx.video_resolution.frame_width *
1267 drv_ctx.video_resolution.frame_height >
1268 m_decoder_capability.max_width *
1269 m_decoder_capability.max_height) ||
1270 (drv_ctx.video_resolution.frame_width*
1271 drv_ctx.video_resolution.frame_height <
1272 m_decoder_capability.min_width *
1273 m_decoder_capability.min_height)) {
1274 DEBUG_PRINT_ERROR(
1275 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1276 drv_ctx.video_resolution.frame_width,
1277 drv_ctx.video_resolution.frame_height,
1278 m_decoder_capability.min_width,
1279 m_decoder_capability.min_height,
1280 m_decoder_capability.max_width,
1281 m_decoder_capability.max_height);
1282 return OMX_ErrorUnsupportedSetting;
1283 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001284 DEBUG_PRINT_HIGH("video session supported");
Arun Menon906de572013-06-18 17:01:40 -07001285 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001286}
1287
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001288int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1289{
1290 if (m_debug.in_buffer_log && !m_debug.infile) {
1291 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1292 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1293 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1294 }
1295 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1296 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); }
1297 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1298 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
1299 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1300 }
1301 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
1302 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1303 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1304 }
1305 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1306 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1307 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1308 }
1309 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1310 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1311 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1312 }
1313 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1314 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1315 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1316 }
1317 m_debug.infile = fopen (m_debug.infile_name, "ab");
1318 if (!m_debug.infile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001319 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001320 m_debug.infile_name[0] = '\0';
1321 return -1;
1322 }
1323 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1324 struct ivf_file_header {
1325 OMX_U8 signature[4]; //='DKIF';
1326 OMX_U8 version ; //= 0;
1327 OMX_U8 headersize ; //= 32;
1328 OMX_U32 FourCC;
1329 OMX_U8 width;
1330 OMX_U8 height;
1331 OMX_U32 rate;
1332 OMX_U32 scale;
1333 OMX_U32 length;
1334 OMX_U8 unused[4];
1335 } file_header;
1336
1337 memset((void *)&file_header,0,sizeof(file_header));
1338 file_header.signature[0] = 'D';
1339 file_header.signature[1] = 'K';
1340 file_header.signature[2] = 'I';
1341 file_header.signature[3] = 'F';
1342 file_header.version = 0;
1343 file_header.headersize = 32;
1344 file_header.FourCC = 0x30385056;
1345 fwrite((const char *)&file_header,
1346 sizeof(file_header),1,m_debug.infile);
1347 }
1348 }
1349 if (m_debug.infile && buffer_addr && buffer_len) {
1350 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1351 struct vp8_ivf_frame_header {
1352 OMX_U32 framesize;
1353 OMX_U32 timestamp_lo;
1354 OMX_U32 timestamp_hi;
1355 } vp8_frame_header;
1356 vp8_frame_header.framesize = buffer_len;
1357 /* Currently FW doesn't use timestamp values */
1358 vp8_frame_header.timestamp_lo = 0;
1359 vp8_frame_header.timestamp_hi = 0;
1360 fwrite((const char *)&vp8_frame_header,
1361 sizeof(vp8_frame_header),1,m_debug.infile);
1362 }
1363 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1364 }
1365 return 0;
1366}
1367
1368int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1369 if (m_debug.out_buffer_log && !m_debug.outfile) {
1370 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1371 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1372 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1373 if (!m_debug.outfile) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001374 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001375 m_debug.outfile_name[0] = '\0';
1376 return -1;
1377 }
1378 }
1379 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1380 int buf_index = buffer - m_out_mem_ptr;
1381 int stride = drv_ctx.video_resolution.stride;
1382 int scanlines = drv_ctx.video_resolution.scan_lines;
1383 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1384 unsigned i;
1385 int bytes_written = 0;
1386 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1387 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1388 temp += stride;
1389 }
1390 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1391 int stride_c = stride;
1392 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1393 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1394 temp += stride_c;
1395 }
1396 }
1397 return 0;
1398}
1399
Shalaj Jain273b3e02012-06-22 19:08:03 -07001400/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001401 FUNCTION
1402 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001403
Arun Menon906de572013-06-18 17:01:40 -07001404 DESCRIPTION
1405 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001406
Arun Menon906de572013-06-18 17:01:40 -07001407 PARAMETERS
1408 ctxt -- Context information related to the self.
1409 id -- Event identifier. This could be any of the following:
1410 1. Command completion event
1411 2. Buffer done callback event
1412 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001413
Arun Menon906de572013-06-18 17:01:40 -07001414 RETURN VALUE
1415 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001416
Arun Menon906de572013-06-18 17:01:40 -07001417 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001418OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1419{
1420
Arun Menon906de572013-06-18 17:01:40 -07001421 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1422 struct v4l2_fmtdesc fdesc;
1423 struct v4l2_format fmt;
1424 struct v4l2_requestbuffers bufreq;
1425 struct v4l2_control control;
1426 struct v4l2_frmsizeenum frmsize;
1427 unsigned int alignment = 0,buffer_size = 0;
1428 int fds[2];
1429 int r,ret=0;
1430 bool codec_ambiguous = false;
1431 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Sachin Shahc82a18f2013-03-29 14:45:38 -07001432
1433#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001434 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001435 property_get("ro.board.platform", platform_name, "0");
1436 if (!strncmp(platform_name, "msm8610", 7)) {
1437 device_name = (OMX_STRING)"/dev/video/q6_dec";
1438 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001439#endif
1440
Arun Menon906de572013-06-18 17:01:40 -07001441 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1442 struct v4l2_control control;
1443 secure_mode = true;
1444 arbitrary_bytes = false;
1445 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301446 } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
1447 OMX_MAX_STRINGNAME_SIZE)){
1448 secure_mode = true;
1449 arbitrary_bytes = false;
1450 role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
Arun Menon906de572013-06-18 17:01:40 -07001451 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001452
Arun Menon906de572013-06-18 17:01:40 -07001453 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001454
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001455 DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d",
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001456 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001457
Arun Menon906de572013-06-18 17:01:40 -07001458 if (drv_ctx.video_driver_fd == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001459 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
Arun Menon906de572013-06-18 17:01:40 -07001460 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1461 close(0);
1462 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001463
Arun Menon906de572013-06-18 17:01:40 -07001464 if (drv_ctx.video_driver_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001465 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
Arun Menon906de572013-06-18 17:01:40 -07001466 return OMX_ErrorInsufficientResources;
1467 }
1468 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1469 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001470
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001471 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001472 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001473 async_thread_created = true;
1474 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1475 }
1476 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001477 DEBUG_PRINT_ERROR("Failed to create async_message_thread");
Arun Menon906de572013-06-18 17:01:40 -07001478 async_thread_created = false;
1479 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001480 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001481
Shalaj Jain273b3e02012-06-22 19:08:03 -07001482#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07001483 outputExtradataFile = fopen (ouputextradatafilename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001484#endif
1485
Arun Menon906de572013-06-18 17:01:40 -07001486 // Copy the role information which provides the decoder kind
1487 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001488
Arun Menon906de572013-06-18 17:01:40 -07001489 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1490 OMX_MAX_STRINGNAME_SIZE)) {
1491 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1492 OMX_MAX_STRINGNAME_SIZE);
1493 drv_ctx.timestamp_adjust = true;
1494 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1495 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1496 output_capability=V4L2_PIX_FMT_MPEG4;
1497 /*Initialize Start Code for MPEG4*/
1498 codec_type_parse = CODEC_TYPE_MPEG4;
1499 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001500 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1501 OMX_MAX_STRINGNAME_SIZE)) {
1502 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1503 OMX_MAX_STRINGNAME_SIZE);
1504 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1505 output_capability = V4L2_PIX_FMT_MPEG2;
1506 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1507 /*Initialize Start Code for MPEG2*/
1508 codec_type_parse = CODEC_TYPE_MPEG2;
1509 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001510 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1511 OMX_MAX_STRINGNAME_SIZE)) {
1512 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001513 DEBUG_PRINT_LOW("H263 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001514 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1515 eCompressionFormat = OMX_VIDEO_CodingH263;
1516 output_capability = V4L2_PIX_FMT_H263;
1517 codec_type_parse = CODEC_TYPE_H263;
1518 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001519 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1520 OMX_MAX_STRINGNAME_SIZE)) {
1521 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001522 DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001523 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1524 output_capability = V4L2_PIX_FMT_DIVX_311;
1525 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1526 codec_type_parse = CODEC_TYPE_DIVX;
1527 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001528
Arun Menon906de572013-06-18 17:01:40 -07001529 eRet = createDivxDrmContext();
1530 if (eRet != OMX_ErrorNone) {
1531 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1532 return eRet;
1533 }
1534 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1535 OMX_MAX_STRINGNAME_SIZE)) {
1536 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001537 DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001538 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1539 output_capability = V4L2_PIX_FMT_DIVX;
1540 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1541 codec_type_parse = CODEC_TYPE_DIVX;
1542 codec_ambiguous = true;
1543 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001544
Arun Menon906de572013-06-18 17:01:40 -07001545 eRet = createDivxDrmContext();
1546 if (eRet != OMX_ErrorNone) {
1547 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1548 return eRet;
1549 }
1550 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1551 OMX_MAX_STRINGNAME_SIZE)) {
1552 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001553 DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
Arun Menon906de572013-06-18 17:01:40 -07001554 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1555 output_capability = V4L2_PIX_FMT_DIVX;
1556 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1557 codec_type_parse = CODEC_TYPE_DIVX;
1558 codec_ambiguous = true;
1559 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001560
Arun Menon906de572013-06-18 17:01:40 -07001561 eRet = createDivxDrmContext();
1562 if (eRet != OMX_ErrorNone) {
1563 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1564 return eRet;
1565 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001566
Arun Menon906de572013-06-18 17:01:40 -07001567 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1568 OMX_MAX_STRINGNAME_SIZE)) {
1569 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1570 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1571 output_capability=V4L2_PIX_FMT_H264;
1572 eCompressionFormat = OMX_VIDEO_CodingAVC;
1573 codec_type_parse = CODEC_TYPE_H264;
1574 m_frame_parser.init_start_codes (codec_type_parse);
1575 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001576 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1577 OMX_MAX_STRINGNAME_SIZE)) {
1578 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1579 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1580 eCompressionFormat = OMX_VIDEO_CodingWMV;
1581 codec_type_parse = CODEC_TYPE_VC1;
1582 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1583 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001584 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1585 OMX_MAX_STRINGNAME_SIZE)) {
1586 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1587 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1588 eCompressionFormat = OMX_VIDEO_CodingWMV;
1589 codec_type_parse = CODEC_TYPE_VC1;
1590 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1591 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001592 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1593 OMX_MAX_STRINGNAME_SIZE)) {
1594 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1595 output_capability=V4L2_PIX_FMT_VP8;
1596 eCompressionFormat = OMX_VIDEO_CodingVPX;
1597 codec_type_parse = CODEC_TYPE_VP8;
1598 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001599
Arun Menon906de572013-06-18 17:01:40 -07001600 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001601 DEBUG_PRINT_ERROR("ERROR:Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07001602 eRet = OMX_ErrorInvalidComponentName;
1603 }
Arun Menon906de572013-06-18 17:01:40 -07001604 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001605
Arun Menon906de572013-06-18 17:01:40 -07001606 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001607 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1608 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1609 if (!client_buffers.set_color_format(dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001610 DEBUG_PRINT_ERROR("Setting color format failed");
Vinay Kaliada4f4422013-01-09 10:45:03 -08001611 eRet = OMX_ErrorInsufficientResources;
1612 }
1613
Arun Menon906de572013-06-18 17:01:40 -07001614 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001615
Arun Menon906de572013-06-18 17:01:40 -07001616 struct v4l2_capability cap;
1617 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1618 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001619 DEBUG_PRINT_ERROR("Failed to query capabilities");
Arun Menon906de572013-06-18 17:01:40 -07001620 /*TODO: How to handle this case */
1621 } else {
1622 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001623 " version = %d, capabilities = %x", cap.driver, cap.card,
Arun Menon906de572013-06-18 17:01:40 -07001624 cap.bus_info, cap.version, cap.capabilities);
1625 }
1626 ret=0;
1627 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1628 fdesc.index=0;
1629 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001630 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001631 fdesc.pixelformat, fdesc.flags);
1632 fdesc.index++;
1633 }
1634 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1635 fdesc.index=0;
1636 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001637
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001638 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
Arun Menon906de572013-06-18 17:01:40 -07001639 fdesc.pixelformat, fdesc.flags);
1640 fdesc.index++;
1641 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001642 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001643 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1644 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1645 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1646 fmt.fmt.pix_mp.pixelformat = output_capability;
1647 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1648 if (ret) {
1649 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001650 DEBUG_PRINT_ERROR("Failed to set format on output port");
Arun Menon906de572013-06-18 17:01:40 -07001651 return OMX_ErrorInsufficientResources;
1652 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001653 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001654 if (codec_ambiguous) {
1655 if (output_capability == V4L2_PIX_FMT_DIVX) {
1656 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001657
Arun Menon906de572013-06-18 17:01:40 -07001658 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1659 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1660 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1661 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1662 } else {
1663 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1664 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001665
Arun Menon906de572013-06-18 17:01:40 -07001666 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1667 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1668 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001669 DEBUG_PRINT_ERROR("Failed to set divx version");
Arun Menon906de572013-06-18 17:01:40 -07001670 }
1671 } else {
1672 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1673 }
1674 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001675
Arun Menon906de572013-06-18 17:01:40 -07001676 //Get the hardware capabilities
1677 memset((void *)&frmsize,0,sizeof(frmsize));
1678 frmsize.index = 0;
1679 frmsize.pixel_format = output_capability;
1680 ret = ioctl(drv_ctx.video_driver_fd,
1681 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1682 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001683 DEBUG_PRINT_ERROR("Failed to get framesizes");
Arun Menon906de572013-06-18 17:01:40 -07001684 return OMX_ErrorHardware;
1685 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001686
Arun Menon906de572013-06-18 17:01:40 -07001687 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1688 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1689 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1690 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1691 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1692 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001693
Arun Menon906de572013-06-18 17:01:40 -07001694 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1695 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1696 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1697 fmt.fmt.pix_mp.pixelformat = capture_capability;
1698 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1699 if (ret) {
1700 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001701 DEBUG_PRINT_ERROR("Failed to set format on capture port");
Arun Menon906de572013-06-18 17:01:40 -07001702 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001703 DEBUG_PRINT_HIGH("Set Format was successful");
Arun Menon906de572013-06-18 17:01:40 -07001704 if (secure_mode) {
1705 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1706 control.value = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001707 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001708 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1709 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001710 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
Arun Menon906de572013-06-18 17:01:40 -07001711 return OMX_ErrorInsufficientResources;
1712 }
1713 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001714
Arun Menon906de572013-06-18 17:01:40 -07001715 /*Get the Buffer requirements for input and output ports*/
1716 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1717 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1718 if (secure_mode) {
1719 drv_ctx.op_buf.alignment=SZ_1M;
1720 drv_ctx.ip_buf.alignment=SZ_1M;
1721 } else {
1722 drv_ctx.op_buf.alignment=SZ_4K;
1723 drv_ctx.ip_buf.alignment=SZ_4K;
1724 }
1725 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1726 drv_ctx.extradata = 0;
1727 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1728 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1729 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1730 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1731 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001732
Vinay Kalia5713bb32013-01-16 18:39:59 -08001733 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001734#ifdef DEFAULT_EXTRADATA
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05301735 if (eRet == OMX_ErrorNone)
Vinay Kalia5713bb32013-01-16 18:39:59 -08001736 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001737#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001738 eRet=get_buffer_req(&drv_ctx.ip_buf);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001739 DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
Vinay Kalia5713bb32013-01-16 18:39:59 -08001740 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001741 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1742 if (m_frame_parser.mutils == NULL) {
1743 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001744
Arun Menon906de572013-06-18 17:01:40 -07001745 if (m_frame_parser.mutils == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001746 DEBUG_PRINT_ERROR("parser utils Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001747 eRet = OMX_ErrorInsufficientResources;
1748 } else {
1749 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1750 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1751 h264_scratch.nFilledLen = 0;
1752 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001753
Arun Menon906de572013-06-18 17:01:40 -07001754 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001755 DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07001756 return OMX_ErrorInsufficientResources;
1757 }
1758 m_frame_parser.mutils->initialize_frame_checking_environment();
1759 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1760 }
1761 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001762
Arun Menon906de572013-06-18 17:01:40 -07001763 h264_parser = new h264_stream_parser();
1764 if (!h264_parser) {
1765 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1766 eRet = OMX_ErrorInsufficientResources;
1767 }
1768 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001769
Arun Menon906de572013-06-18 17:01:40 -07001770 if (pipe(fds)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001771 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001772 eRet = OMX_ErrorInsufficientResources;
1773 } else {
1774 int temp1[2];
1775 if (fds[0] == 0 || fds[1] == 0) {
1776 if (pipe (temp1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001777 DEBUG_PRINT_ERROR("pipe creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001778 return OMX_ErrorInsufficientResources;
1779 }
1780 //close (fds[0]);
1781 //close (fds[1]);
1782 fds[0] = temp1 [0];
1783 fds[1] = temp1 [1];
1784 }
1785 m_pipe_in = fds[0];
1786 m_pipe_out = fds[1];
1787 msg_thread_created = true;
1788 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001789
Arun Menon906de572013-06-18 17:01:40 -07001790 if (r < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001791 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
Arun Menon906de572013-06-18 17:01:40 -07001792 msg_thread_created = false;
1793 eRet = OMX_ErrorInsufficientResources;
1794 }
1795 }
1796 }
1797
1798 if (eRet != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001799 DEBUG_PRINT_ERROR("Component Init Failed");
Arun Menon906de572013-06-18 17:01:40 -07001800 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001801 DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
Arun Menon906de572013-06-18 17:01:40 -07001802 }
1803 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1804 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001805}
1806
1807/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001808 FUNCTION
1809 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001810
Arun Menon906de572013-06-18 17:01:40 -07001811 DESCRIPTION
1812 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001813
Arun Menon906de572013-06-18 17:01:40 -07001814 PARAMETERS
1815 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001816
Arun Menon906de572013-06-18 17:01:40 -07001817 RETURN VALUE
1818 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001819
Arun Menon906de572013-06-18 17:01:40 -07001820 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001821OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001822(
1823 OMX_IN OMX_HANDLETYPE hComp,
1824 OMX_OUT OMX_STRING componentName,
1825 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1826 OMX_OUT OMX_VERSIONTYPE* specVersion,
1827 OMX_OUT OMX_UUIDTYPE* componentUUID
1828 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001829{
Arun Menon906de572013-06-18 17:01:40 -07001830 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001831 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001832 return OMX_ErrorInvalidState;
1833 }
Arun Menon906de572013-06-18 17:01:40 -07001834 /* TBD -- Return the proper version */
1835 if (specVersion) {
1836 specVersion->nVersion = OMX_SPEC_VERSION;
1837 }
1838 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001839}
1840/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001841 FUNCTION
1842 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001843
Arun Menon906de572013-06-18 17:01:40 -07001844 DESCRIPTION
1845 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001846
Arun Menon906de572013-06-18 17:01:40 -07001847 PARAMETERS
1848 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001849
Arun Menon906de572013-06-18 17:01:40 -07001850 RETURN VALUE
1851 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001852
Arun Menon906de572013-06-18 17:01:40 -07001853 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001854OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001855 OMX_IN OMX_COMMANDTYPE cmd,
1856 OMX_IN OMX_U32 param1,
1857 OMX_IN OMX_PTR cmdData
1858 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001859{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001860 DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001861 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001862 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001863 return OMX_ErrorInvalidState;
1864 }
1865 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001866 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001867 DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
Arun Menon906de572013-06-18 17:01:40 -07001868 "to invalid port: %lu", param1);
1869 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001870 }
1871 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1872 sem_wait(&m_cmd_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001873 DEBUG_PRINT_LOW("send_command: Command Processed");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001874 return OMX_ErrorNone;
1875}
1876
1877/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001878 FUNCTION
1879 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001880
Arun Menon906de572013-06-18 17:01:40 -07001881 DESCRIPTION
1882 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001883
Arun Menon906de572013-06-18 17:01:40 -07001884 PARAMETERS
1885 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001886
Arun Menon906de572013-06-18 17:01:40 -07001887 RETURN VALUE
1888 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001889
Arun Menon906de572013-06-18 17:01:40 -07001890 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001891OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001892 OMX_IN OMX_COMMANDTYPE cmd,
1893 OMX_IN OMX_U32 param1,
1894 OMX_IN OMX_PTR cmdData
1895 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001896{
Arun Menon906de572013-06-18 17:01:40 -07001897 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1898 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1899 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001900
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001901 DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
1902 DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
Arun Menon906de572013-06-18 17:01:40 -07001903 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001904
Arun Menon906de572013-06-18 17:01:40 -07001905 if (cmd == OMX_CommandStateSet) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001906 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
1907 DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
Arun Menon906de572013-06-18 17:01:40 -07001908 /***************************/
1909 /* Current State is Loaded */
1910 /***************************/
1911 if (m_state == OMX_StateLoaded) {
1912 if (eState == OMX_StateIdle) {
1913 //if all buffers are allocated or all ports disabled
1914 if (allocate_done() ||
1915 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001916 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07001917 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001918 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
Arun Menon906de572013-06-18 17:01:40 -07001919 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1920 // Skip the event notification
1921 bFlag = 0;
1922 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001923 }
Arun Menon906de572013-06-18 17:01:40 -07001924 /* Requesting transition from Loaded to Loaded */
1925 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001926 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07001927 post_event(OMX_EventError,OMX_ErrorSameState,\
1928 OMX_COMPONENT_GENERATE_EVENT);
1929 eRet = OMX_ErrorSameState;
1930 }
1931 /* Requesting transition from Loaded to WaitForResources */
1932 else if (eState == OMX_StateWaitForResources) {
1933 /* Since error is None , we will post an event
1934 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001935 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07001936 }
1937 /* Requesting transition from Loaded to Executing */
1938 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001939 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001940 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1941 OMX_COMPONENT_GENERATE_EVENT);
1942 eRet = OMX_ErrorIncorrectStateTransition;
1943 }
1944 /* Requesting transition from Loaded to Pause */
1945 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001946 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07001947 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1948 OMX_COMPONENT_GENERATE_EVENT);
1949 eRet = OMX_ErrorIncorrectStateTransition;
1950 }
1951 /* Requesting transition from Loaded to Invalid */
1952 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001953 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07001954 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1955 eRet = OMX_ErrorInvalidState;
1956 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001957 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
Arun Menon906de572013-06-18 17:01:40 -07001958 eState);
1959 eRet = OMX_ErrorBadParameter;
1960 }
1961 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001962
Arun Menon906de572013-06-18 17:01:40 -07001963 /***************************/
1964 /* Current State is IDLE */
1965 /***************************/
1966 else if (m_state == OMX_StateIdle) {
1967 if (eState == OMX_StateLoaded) {
1968 if (release_done()) {
1969 /*
1970 Since error is None , we will post an event at the end
1971 of this function definition
1972 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001973 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07001974 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001975 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
Arun Menon906de572013-06-18 17:01:40 -07001976 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1977 // Skip the event notification
1978 bFlag = 0;
1979 }
1980 }
1981 /* Requesting transition from Idle to Executing */
1982 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001983 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001984 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1985 bFlag = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001986 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07001987 m_state=OMX_StateExecuting;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001988 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
Arun Menon906de572013-06-18 17:01:40 -07001989 }
1990 /* Requesting transition from Idle to Idle */
1991 else if (eState == OMX_StateIdle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001992 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
Arun Menon906de572013-06-18 17:01:40 -07001993 post_event(OMX_EventError,OMX_ErrorSameState,\
1994 OMX_COMPONENT_GENERATE_EVENT);
1995 eRet = OMX_ErrorSameState;
1996 }
1997 /* Requesting transition from Idle to WaitForResources */
1998 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07001999 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002000 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2001 OMX_COMPONENT_GENERATE_EVENT);
2002 eRet = OMX_ErrorIncorrectStateTransition;
2003 }
2004 /* Requesting transition from Idle to Pause */
2005 else if (eState == OMX_StatePause) {
2006 /*To pause the Video core we need to start the driver*/
2007 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2008 NULL) < */0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002009 DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
Arun Menon906de572013-06-18 17:01:40 -07002010 omx_report_error ();
2011 eRet = OMX_ErrorHardware;
2012 } else {
2013 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002014 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002015 bFlag = 0;
2016 }
2017 }
2018 /* Requesting transition from Idle to Invalid */
2019 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002020 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002021 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2022 eRet = OMX_ErrorInvalidState;
2023 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002024 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002025 eRet = OMX_ErrorBadParameter;
2026 }
2027 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002028
Arun Menon906de572013-06-18 17:01:40 -07002029 /******************************/
2030 /* Current State is Executing */
2031 /******************************/
2032 else if (m_state == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002033 DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
Arun Menon906de572013-06-18 17:01:40 -07002034 /* Requesting transition from Executing to Idle */
2035 if (eState == OMX_StateIdle) {
2036 /* Since error is None , we will post an event
2037 at the end of this function definition
2038 */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002039 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002040 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2041 if (!sem_posted) {
2042 sem_posted = 1;
2043 sem_post (&m_cmd_lock);
2044 execute_omx_flush(OMX_ALL);
2045 }
2046 bFlag = 0;
2047 }
2048 /* Requesting transition from Executing to Paused */
2049 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002050 DEBUG_PRINT_LOW("PAUSE Command Issued");
Arun Menon906de572013-06-18 17:01:40 -07002051 m_state = OMX_StatePause;
2052 bFlag = 1;
2053 }
2054 /* Requesting transition from Executing to Loaded */
2055 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002056 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002057 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2058 OMX_COMPONENT_GENERATE_EVENT);
2059 eRet = OMX_ErrorIncorrectStateTransition;
2060 }
2061 /* Requesting transition from Executing to WaitForResources */
2062 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002063 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002064 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2065 OMX_COMPONENT_GENERATE_EVENT);
2066 eRet = OMX_ErrorIncorrectStateTransition;
2067 }
2068 /* Requesting transition from Executing to Executing */
2069 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002070 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002071 post_event(OMX_EventError,OMX_ErrorSameState,\
2072 OMX_COMPONENT_GENERATE_EVENT);
2073 eRet = OMX_ErrorSameState;
2074 }
2075 /* Requesting transition from Executing to Invalid */
2076 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002077 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002078 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2079 eRet = OMX_ErrorInvalidState;
2080 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002081 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002082 eRet = OMX_ErrorBadParameter;
2083 }
2084 }
2085 /***************************/
2086 /* Current State is Pause */
2087 /***************************/
2088 else if (m_state == OMX_StatePause) {
2089 /* Requesting transition from Pause to Executing */
2090 if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002091 DEBUG_PRINT_LOW("Pause --> Executing");
Arun Menon906de572013-06-18 17:01:40 -07002092 m_state = OMX_StateExecuting;
2093 bFlag = 1;
2094 }
2095 /* Requesting transition from Pause to Idle */
2096 else if (eState == OMX_StateIdle) {
2097 /* Since error is None , we will post an event
2098 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002099 DEBUG_PRINT_LOW("Pause --> Idle");
Arun Menon906de572013-06-18 17:01:40 -07002100 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2101 if (!sem_posted) {
2102 sem_posted = 1;
2103 sem_post (&m_cmd_lock);
2104 execute_omx_flush(OMX_ALL);
2105 }
2106 bFlag = 0;
2107 }
2108 /* Requesting transition from Pause to loaded */
2109 else if (eState == OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002110 DEBUG_PRINT_ERROR("Pause --> loaded");
Arun Menon906de572013-06-18 17:01:40 -07002111 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2112 OMX_COMPONENT_GENERATE_EVENT);
2113 eRet = OMX_ErrorIncorrectStateTransition;
2114 }
2115 /* Requesting transition from Pause to WaitForResources */
2116 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002117 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002118 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2119 OMX_COMPONENT_GENERATE_EVENT);
2120 eRet = OMX_ErrorIncorrectStateTransition;
2121 }
2122 /* Requesting transition from Pause to Pause */
2123 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002124 DEBUG_PRINT_ERROR("Pause --> Pause");
Arun Menon906de572013-06-18 17:01:40 -07002125 post_event(OMX_EventError,OMX_ErrorSameState,\
2126 OMX_COMPONENT_GENERATE_EVENT);
2127 eRet = OMX_ErrorSameState;
2128 }
2129 /* Requesting transition from Pause to Invalid */
2130 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002131 DEBUG_PRINT_ERROR("Pause --> Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002132 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2133 eRet = OMX_ErrorInvalidState;
2134 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002135 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
Arun Menon906de572013-06-18 17:01:40 -07002136 eRet = OMX_ErrorBadParameter;
2137 }
2138 }
2139 /***************************/
2140 /* Current State is WaitForResources */
2141 /***************************/
2142 else if (m_state == OMX_StateWaitForResources) {
2143 /* Requesting transition from WaitForResources to Loaded */
2144 if (eState == OMX_StateLoaded) {
2145 /* Since error is None , we will post an event
2146 at the end of this function definition */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002147 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002148 }
2149 /* Requesting transition from WaitForResources to WaitForResources */
2150 else if (eState == OMX_StateWaitForResources) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002151 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
Arun Menon906de572013-06-18 17:01:40 -07002152 post_event(OMX_EventError,OMX_ErrorSameState,
2153 OMX_COMPONENT_GENERATE_EVENT);
2154 eRet = OMX_ErrorSameState;
2155 }
2156 /* Requesting transition from WaitForResources to Executing */
2157 else if (eState == OMX_StateExecuting) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002158 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07002159 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2160 OMX_COMPONENT_GENERATE_EVENT);
2161 eRet = OMX_ErrorIncorrectStateTransition;
2162 }
2163 /* Requesting transition from WaitForResources to Pause */
2164 else if (eState == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002165 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
Arun Menon906de572013-06-18 17:01:40 -07002166 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2167 OMX_COMPONENT_GENERATE_EVENT);
2168 eRet = OMX_ErrorIncorrectStateTransition;
2169 }
2170 /* Requesting transition from WaitForResources to Invalid */
2171 else if (eState == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002172 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
Arun Menon906de572013-06-18 17:01:40 -07002173 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2174 eRet = OMX_ErrorInvalidState;
2175 }
2176 /* Requesting transition from WaitForResources to Loaded -
2177 is NOT tested by Khronos TS */
2178
2179 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002180 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
Arun Menon906de572013-06-18 17:01:40 -07002181 eRet = OMX_ErrorBadParameter;
2182 }
2183 }
2184 /********************************/
2185 /* Current State is Invalid */
2186 /*******************************/
2187 else if (m_state == OMX_StateInvalid) {
2188 /* State Transition from Inavlid to any state */
2189 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2190 || OMX_StateIdle || OMX_StateExecuting
2191 || OMX_StatePause || OMX_StateInvalid)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002192 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
Arun Menon906de572013-06-18 17:01:40 -07002193 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2194 OMX_COMPONENT_GENERATE_EVENT);
2195 eRet = OMX_ErrorInvalidState;
2196 }
2197 } else if (cmd == OMX_CommandFlush) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002198 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
Arun Menon906de572013-06-18 17:01:40 -07002199 "with param1: %lu", param1);
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002200#ifdef _MSM8974_
2201 send_codec_config();
2202#endif
Arun Menon906de572013-06-18 17:01:40 -07002203 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2204 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2205 }
2206 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2207 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2208 }
2209 if (!sem_posted) {
2210 sem_posted = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002211 DEBUG_PRINT_LOW("Set the Semaphore");
Arun Menon906de572013-06-18 17:01:40 -07002212 sem_post (&m_cmd_lock);
2213 execute_omx_flush(param1);
2214 }
2215 bFlag = 0;
2216 } else if ( cmd == OMX_CommandPortEnable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002217 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
Arun Menon906de572013-06-18 17:01:40 -07002218 "with param1: %lu", param1);
2219 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2220 m_inp_bEnabled = OMX_TRUE;
2221
2222 if ( (m_state == OMX_StateLoaded &&
2223 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2224 || allocate_input_done()) {
2225 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2226 OMX_COMPONENT_GENERATE_EVENT);
2227 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002228 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002229 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2230 // Skip the event notification
2231 bFlag = 0;
2232 }
2233 }
2234 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002235 DEBUG_PRINT_LOW("Enable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002236 m_out_bEnabled = OMX_TRUE;
2237
2238 if ( (m_state == OMX_StateLoaded &&
2239 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2240 || (allocate_output_done())) {
2241 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2242 OMX_COMPONENT_GENERATE_EVENT);
2243
2244 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002245 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
Arun Menon906de572013-06-18 17:01:40 -07002246 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2247 // Skip the event notification
2248 bFlag = 0;
2249 }
2250 }
2251 } else if (cmd == OMX_CommandPortDisable) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002252 DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
Arun Menon906de572013-06-18 17:01:40 -07002253 "with param1: %lu", param1);
2254 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07002255 codec_config_flag = false;
Arun Menon906de572013-06-18 17:01:40 -07002256 m_inp_bEnabled = OMX_FALSE;
2257 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2258 && release_input_done()) {
2259 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2260 OMX_COMPONENT_GENERATE_EVENT);
2261 } else {
2262 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2263 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2264 if (!sem_posted) {
2265 sem_posted = 1;
2266 sem_post (&m_cmd_lock);
2267 }
2268 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2269 }
2270
2271 // Skip the event notification
2272 bFlag = 0;
2273 }
2274 }
2275 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2276 m_out_bEnabled = OMX_FALSE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002277 DEBUG_PRINT_LOW("Disable output Port command recieved");
Arun Menon906de572013-06-18 17:01:40 -07002278 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2279 && release_output_done()) {
2280 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2281 OMX_COMPONENT_GENERATE_EVENT);
2282 } else {
2283 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2284 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2285 if (!sem_posted) {
2286 sem_posted = 1;
2287 sem_post (&m_cmd_lock);
2288 }
2289 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2290 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2291 }
2292 // Skip the event notification
2293 bFlag = 0;
2294
2295 }
2296 }
2297 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002298 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
Arun Menon906de572013-06-18 17:01:40 -07002299 eRet = OMX_ErrorNotImplemented;
2300 }
2301 if (eRet == OMX_ErrorNone && bFlag) {
2302 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2303 }
2304 if (!sem_posted) {
2305 sem_post(&m_cmd_lock);
2306 }
2307
2308 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002309}
2310
2311/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002312 FUNCTION
2313 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002314
Arun Menon906de572013-06-18 17:01:40 -07002315 DESCRIPTION
2316 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002317
Arun Menon906de572013-06-18 17:01:40 -07002318 PARAMETERS
2319 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002320
Arun Menon906de572013-06-18 17:01:40 -07002321 RETURN VALUE
2322 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002323
Arun Menon906de572013-06-18 17:01:40 -07002324 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002325bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2326{
Arun Menon906de572013-06-18 17:01:40 -07002327 bool bRet = false;
2328 struct v4l2_plane plane;
2329 struct v4l2_buffer v4l2_buf;
2330 struct v4l2_decoder_cmd dec;
Surajit Podderd2644d52013-08-28 17:59:06 +05302331 DEBUG_PRINT_LOW("in %s, flushing %lu", __func__, flushType);
Arun Menon906de572013-06-18 17:01:40 -07002332 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2333 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002334
Arun Menon906de572013-06-18 17:01:40 -07002335 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002336
Arun Menon906de572013-06-18 17:01:40 -07002337 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2338 output_flush_progress = true;
2339 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2340 } else {
2341 /* XXX: The driver/hardware does not support flushing of individual ports
2342 * in all states. So we pretty much need to flush both ports internally,
2343 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2344 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2345 * we automatically omit sending the FLUSH done for the "opposite" port. */
2346 input_flush_progress = true;
2347 output_flush_progress = true;
2348 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2349 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002350
Arun Menon906de572013-06-18 17:01:40 -07002351 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002352 DEBUG_PRINT_ERROR("Flush Port (%lu) Failed ", flushType);
Arun Menon906de572013-06-18 17:01:40 -07002353 bRet = false;
2354 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002355
Arun Menon906de572013-06-18 17:01:40 -07002356 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002357}
2358/*=========================================================================
2359FUNCTION : execute_output_flush
2360
2361DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002362Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002363
2364PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002365None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002366
2367RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002368true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002369==========================================================================*/
2370bool omx_vdec::execute_output_flush()
2371{
Arun Menon906de572013-06-18 17:01:40 -07002372 unsigned p1 = 0; // Parameter - 1
2373 unsigned p2 = 0; // Parameter - 2
2374 unsigned ident = 0;
2375 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002376
Arun Menon906de572013-06-18 17:01:40 -07002377 /*Generate FBD for all Buffers in the FTBq*/
2378 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002379 DEBUG_PRINT_LOW("Initiate Output Flush");
Arun Menon906de572013-06-18 17:01:40 -07002380 while (m_ftb_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002381 DEBUG_PRINT_LOW("Buffer queue size %d pending buf cnt %d",
Arun Menon906de572013-06-18 17:01:40 -07002382 m_ftb_q.m_size,pending_output_buffers);
2383 m_ftb_q.pop_entry(&p1,&p2,&ident);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002384 DEBUG_PRINT_LOW("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Arun Menon906de572013-06-18 17:01:40 -07002385 if (ident == m_fill_output_msg ) {
2386 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2387 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2388 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2389 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002390 }
Arun Menon906de572013-06-18 17:01:40 -07002391 pthread_mutex_unlock(&m_lock);
2392 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002393
Arun Menon906de572013-06-18 17:01:40 -07002394 if (arbitrary_bytes) {
2395 prev_ts = LLONG_MAX;
2396 rst_prev_ts = true;
2397 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002398 DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002399 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002400}
2401/*=========================================================================
2402FUNCTION : execute_input_flush
2403
2404DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002405Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002406
2407PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002408None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002409
2410RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002411true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002412==========================================================================*/
2413bool omx_vdec::execute_input_flush()
2414{
Arun Menon906de572013-06-18 17:01:40 -07002415 unsigned i =0;
2416 unsigned p1 = 0; // Parameter - 1
2417 unsigned p2 = 0; // Parameter - 2
2418 unsigned ident = 0;
2419 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002420
Arun Menon906de572013-06-18 17:01:40 -07002421 /*Generate EBD for all Buffers in the ETBq*/
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002422 DEBUG_PRINT_LOW("Initiate Input Flush");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002423
Arun Menon906de572013-06-18 17:01:40 -07002424 pthread_mutex_lock(&m_lock);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002425 DEBUG_PRINT_LOW("Check if the Queue is empty");
Arun Menon906de572013-06-18 17:01:40 -07002426 while (m_etb_q.m_size) {
2427 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002428
Arun Menon906de572013-06-18 17:01:40 -07002429 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002430 DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
Arun Menon906de572013-06-18 17:01:40 -07002431 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2432 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2433 pending_input_buffers++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002434 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
Arun Menon906de572013-06-18 17:01:40 -07002435 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2436 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2437 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002438 DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
Arun Menon906de572013-06-18 17:01:40 -07002439 (OMX_BUFFERHEADERTYPE *)p1);
2440 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2441 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002442 }
Arun Menon906de572013-06-18 17:01:40 -07002443 time_stamp_dts.flush_timestamp();
2444 /*Check if Heap Buffers are to be flushed*/
2445 if (arbitrary_bytes && !(codec_config_flag)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002446 DEBUG_PRINT_LOW("Reset all the variables before flusing");
Arun Menon906de572013-06-18 17:01:40 -07002447 h264_scratch.nFilledLen = 0;
2448 nal_count = 0;
2449 look_ahead_nal = false;
2450 frame_count = 0;
2451 h264_last_au_ts = LLONG_MAX;
2452 h264_last_au_flags = 0;
2453 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2454 m_demux_entries = 0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002455 DEBUG_PRINT_LOW("Initialize parser");
Arun Menon906de572013-06-18 17:01:40 -07002456 if (m_frame_parser.mutils) {
2457 m_frame_parser.mutils->initialize_frame_checking_environment();
2458 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002459
Arun Menon906de572013-06-18 17:01:40 -07002460 while (m_input_pending_q.m_size) {
2461 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2462 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2463 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002464
Arun Menon906de572013-06-18 17:01:40 -07002465 if (psource_frame) {
2466 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2467 psource_frame = NULL;
2468 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002469
Arun Menon906de572013-06-18 17:01:40 -07002470 if (pdest_frame) {
2471 pdest_frame->nFilledLen = 0;
2472 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2473 (unsigned int)NULL);
2474 pdest_frame = NULL;
2475 }
2476 m_frame_parser.flush();
2477 } else if (codec_config_flag) {
2478 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2479 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002480 }
Arun Menon906de572013-06-18 17:01:40 -07002481 pthread_mutex_unlock(&m_lock);
2482 input_flush_progress = false;
2483 if (!arbitrary_bytes) {
2484 prev_ts = LLONG_MAX;
2485 rst_prev_ts = true;
2486 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002487#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002488 if (m_debug_timestamp) {
2489 m_timestamp_list.reset_ts_list();
2490 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002491#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002492 DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
Arun Menon906de572013-06-18 17:01:40 -07002493 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002494}
2495
2496
2497/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002498 FUNCTION
2499 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002500
Arun Menon906de572013-06-18 17:01:40 -07002501 DESCRIPTION
2502 Send the event to decoder pipe. This is needed to generate the callbacks
2503 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002504
Arun Menon906de572013-06-18 17:01:40 -07002505 PARAMETERS
2506 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002507
Arun Menon906de572013-06-18 17:01:40 -07002508 RETURN VALUE
2509 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002510
Arun Menon906de572013-06-18 17:01:40 -07002511 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002512bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002513 unsigned int p2,
2514 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002515{
Arun Menon906de572013-06-18 17:01:40 -07002516 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002517
2518
Arun Menon906de572013-06-18 17:01:40 -07002519 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002520
Arun Menon906de572013-06-18 17:01:40 -07002521 if (id == m_fill_output_msg ||
2522 id == OMX_COMPONENT_GENERATE_FBD) {
2523 m_ftb_q.insert_entry(p1,p2,id);
2524 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2525 id == OMX_COMPONENT_GENERATE_EBD ||
2526 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2527 m_etb_q.insert_entry(p1,p2,id);
2528 } else {
2529 m_cmd_q.insert_entry(p1,p2,id);
2530 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002531
Arun Menon906de572013-06-18 17:01:40 -07002532 bRet = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002533 DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
Arun Menon906de572013-06-18 17:01:40 -07002534 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002535
Arun Menon906de572013-06-18 17:01:40 -07002536 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002537
Arun Menon906de572013-06-18 17:01:40 -07002538 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002539}
2540
2541OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2542{
Arun Menon906de572013-06-18 17:01:40 -07002543 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2544 if (!profileLevelType)
2545 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002546
Arun Menon906de572013-06-18 17:01:40 -07002547 if (profileLevelType->nPortIndex == 0) {
2548 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2549 if (profileLevelType->nProfileIndex == 0) {
2550 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2551 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002552
Arun Menon906de572013-06-18 17:01:40 -07002553 } else if (profileLevelType->nProfileIndex == 1) {
2554 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2555 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2556 } else if (profileLevelType->nProfileIndex == 2) {
2557 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2558 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2559 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002560 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu",
Arun Menon906de572013-06-18 17:01:40 -07002561 profileLevelType->nProfileIndex);
2562 eRet = OMX_ErrorNoMore;
2563 }
2564 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2565 if (profileLevelType->nProfileIndex == 0) {
2566 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2567 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2568 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002569 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002570 eRet = OMX_ErrorNoMore;
2571 }
2572 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2573 if (profileLevelType->nProfileIndex == 0) {
2574 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2575 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2576 } else if (profileLevelType->nProfileIndex == 1) {
2577 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2578 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2579 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002580 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
Arun Menon906de572013-06-18 17:01:40 -07002581 eRet = OMX_ErrorNoMore;
2582 }
2583 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2584 eRet = OMX_ErrorNoMore;
2585 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2586 if (profileLevelType->nProfileIndex == 0) {
2587 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2588 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2589 } else if (profileLevelType->nProfileIndex == 1) {
2590 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2591 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
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 {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002597 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07002598 eRet = OMX_ErrorNoMore;
2599 }
2600 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002601 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07002602 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002603 }
Arun Menon906de572013-06-18 17:01:40 -07002604 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002605}
2606
2607/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002608 FUNCTION
2609 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002610
Arun Menon906de572013-06-18 17:01:40 -07002611 DESCRIPTION
2612 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002613
Arun Menon906de572013-06-18 17:01:40 -07002614 PARAMETERS
2615 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002616
Arun Menon906de572013-06-18 17:01:40 -07002617 RETURN VALUE
2618 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002619
Arun Menon906de572013-06-18 17:01:40 -07002620 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002621OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002622 OMX_IN OMX_INDEXTYPE paramIndex,
2623 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002624{
2625 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2626
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002627 DEBUG_PRINT_LOW("get_parameter:");
Arun Menon906de572013-06-18 17:01:40 -07002628 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002629 DEBUG_PRINT_ERROR("Get Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002630 return OMX_ErrorInvalidState;
2631 }
Arun Menon906de572013-06-18 17:01:40 -07002632 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002633 DEBUG_PRINT_LOW("Get Param in Invalid paramData");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002634 return OMX_ErrorBadParameter;
2635 }
Arun Menon906de572013-06-18 17:01:40 -07002636 switch ((unsigned long)paramIndex) {
2637 case OMX_IndexParamPortDefinition: {
2638 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2639 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002640 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
Arun Menon906de572013-06-18 17:01:40 -07002641 eRet = update_portdef(portDefn);
2642 if (eRet == OMX_ErrorNone)
2643 m_port_def = *portDefn;
2644 break;
2645 }
2646 case OMX_IndexParamVideoInit: {
2647 OMX_PORT_PARAM_TYPE *portParamType =
2648 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002649 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002650
Arun Menon906de572013-06-18 17:01:40 -07002651 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2652 portParamType->nSize = sizeof(portParamType);
2653 portParamType->nPorts = 2;
2654 portParamType->nStartPortNumber = 0;
2655 break;
2656 }
2657 case OMX_IndexParamVideoPortFormat: {
2658 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2659 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002660 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002661
Arun Menon906de572013-06-18 17:01:40 -07002662 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2663 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002664
Arun Menon906de572013-06-18 17:01:40 -07002665 if (0 == portFmt->nPortIndex) {
2666 if (0 == portFmt->nIndex) {
2667 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2668 portFmt->eCompressionFormat = eCompressionFormat;
2669 } else {
2670 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002671 " NoMore compression formats");
Arun Menon906de572013-06-18 17:01:40 -07002672 eRet = OMX_ErrorNoMore;
2673 }
2674 } else if (1 == portFmt->nPortIndex) {
2675 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002676
Arun Menon906de572013-06-18 17:01:40 -07002677 if (0 == portFmt->nIndex)
2678 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2679 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2680 else if (1 == portFmt->nIndex)
2681 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2682 else {
2683 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002684 " NoMore Color formats");
Arun Menon906de572013-06-18 17:01:40 -07002685 eRet = OMX_ErrorNoMore;
2686 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002687 DEBUG_PRINT_LOW("returning %d", portFmt->eColorFormat);
Arun Menon906de572013-06-18 17:01:40 -07002688 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002689 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
Arun Menon906de572013-06-18 17:01:40 -07002690 (int)portFmt->nPortIndex);
2691 eRet = OMX_ErrorBadPortIndex;
2692 }
2693 break;
2694 }
2695 /*Component should support this port definition*/
2696 case OMX_IndexParamAudioInit: {
2697 OMX_PORT_PARAM_TYPE *audioPortParamType =
2698 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002699 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
Arun Menon906de572013-06-18 17:01:40 -07002700 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2701 audioPortParamType->nSize = sizeof(audioPortParamType);
2702 audioPortParamType->nPorts = 0;
2703 audioPortParamType->nStartPortNumber = 0;
2704 break;
2705 }
2706 /*Component should support this port definition*/
2707 case OMX_IndexParamImageInit: {
2708 OMX_PORT_PARAM_TYPE *imagePortParamType =
2709 (OMX_PORT_PARAM_TYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002710 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
Arun Menon906de572013-06-18 17:01:40 -07002711 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2712 imagePortParamType->nSize = sizeof(imagePortParamType);
2713 imagePortParamType->nPorts = 0;
2714 imagePortParamType->nStartPortNumber = 0;
2715 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002716
Arun Menon906de572013-06-18 17:01:40 -07002717 }
2718 /*Component should support this port definition*/
2719 case OMX_IndexParamOtherInit: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002720 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
Arun Menon906de572013-06-18 17:01:40 -07002721 paramIndex);
2722 eRet =OMX_ErrorUnsupportedIndex;
2723 break;
2724 }
2725 case OMX_IndexParamStandardComponentRole: {
2726 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2727 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2728 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2729 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002730
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002731 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
Arun Menon906de572013-06-18 17:01:40 -07002732 paramIndex);
2733 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2734 OMX_MAX_STRINGNAME_SIZE);
2735 break;
2736 }
2737 /* Added for parameter test */
2738 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002739
Arun Menon906de572013-06-18 17:01:40 -07002740 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2741 (OMX_PRIORITYMGMTTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002742 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
Arun Menon906de572013-06-18 17:01:40 -07002743 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2744 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002745
Arun Menon906de572013-06-18 17:01:40 -07002746 break;
2747 }
2748 /* Added for parameter test */
2749 case OMX_IndexParamCompBufferSupplier: {
2750 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2751 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002752 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002753
Arun Menon906de572013-06-18 17:01:40 -07002754 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2755 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2756 if (0 == bufferSupplierType->nPortIndex)
2757 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2758 else if (1 == bufferSupplierType->nPortIndex)
2759 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2760 else
2761 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002762
2763
Arun Menon906de572013-06-18 17:01:40 -07002764 break;
2765 }
2766 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002767 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
Arun Menon906de572013-06-18 17:01:40 -07002768 paramIndex);
2769 break;
2770 }
2771 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002772 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002773 paramIndex);
2774 break;
2775 }
2776 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002777 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002778 paramIndex);
2779 break;
2780 }
2781 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002782 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
Arun Menon906de572013-06-18 17:01:40 -07002783 paramIndex);
2784 break;
2785 }
2786 case OMX_IndexParamVideoProfileLevelQuerySupported: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002787 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002788 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2789 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2790 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2791 break;
2792 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002793#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002794 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002795 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
Arun Menon906de572013-06-18 17:01:40 -07002796 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2797 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002798
Arun Menon906de572013-06-18 17:01:40 -07002799 if (secure_mode) {
2800 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2801 GRALLOC_USAGE_PRIVATE_UNCACHED);
2802 } else {
2803 nativeBuffersUsage->nUsage =
2804 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2805 GRALLOC_USAGE_PRIVATE_UNCACHED);
2806 }
2807 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002808 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
Arun Menon906de572013-06-18 17:01:40 -07002809 eRet = OMX_ErrorBadParameter;
2810 }
2811 }
2812 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002813#endif
2814
Arun Menon906de572013-06-18 17:01:40 -07002815 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002816 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07002817 eRet =OMX_ErrorUnsupportedIndex;
2818 }
2819
Shalaj Jain273b3e02012-06-22 19:08:03 -07002820 }
2821
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002822 DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
Arun Menon906de572013-06-18 17:01:40 -07002823 drv_ctx.video_resolution.frame_width,
2824 drv_ctx.video_resolution.frame_height,
2825 drv_ctx.video_resolution.stride,
2826 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002827
Arun Menon906de572013-06-18 17:01:40 -07002828 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002829}
2830
2831#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2832OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2833{
2834 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2835 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2836 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2837
Arun Menon906de572013-06-18 17:01:40 -07002838 if ((params == NULL) ||
2839 (params->nativeBuffer == NULL) ||
2840 (params->nativeBuffer->handle == NULL) ||
2841 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002842 return OMX_ErrorBadParameter;
2843 m_use_android_native_buffers = OMX_TRUE;
2844 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2845 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002846 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 -07002847 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002848 if (!secure_mode) {
2849 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002850 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002851 if (buffer == MAP_FAILED) {
2852 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2853 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002854 }
2855 }
2856 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2857 } else {
2858 eRet = OMX_ErrorBadParameter;
2859 }
2860 return eRet;
2861}
2862#endif
Praveen Chavancf924182013-12-06 23:16:23 -08002863
2864OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
2865 struct v4l2_control control;
2866 struct v4l2_format fmt;
2867 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
2868 control.value = 1;
2869 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
2870 if (rc < 0) {
2871 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
2872 return OMX_ErrorHardware;
2873 }
2874 m_smoothstreaming_mode = true;
2875 return OMX_ErrorNone;
2876}
2877
Shalaj Jain273b3e02012-06-22 19:08:03 -07002878/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002879 FUNCTION
2880 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002881
Arun Menon906de572013-06-18 17:01:40 -07002882 DESCRIPTION
2883 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002884
Arun Menon906de572013-06-18 17:01:40 -07002885 PARAMETERS
2886 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002887
Arun Menon906de572013-06-18 17:01:40 -07002888 RETURN VALUE
2889 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002890
Arun Menon906de572013-06-18 17:01:40 -07002891 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002892OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002893 OMX_IN OMX_INDEXTYPE paramIndex,
2894 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002895{
2896 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002897 int ret=0;
2898 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002899 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002900 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002901 return OMX_ErrorInvalidState;
2902 }
Arun Menon906de572013-06-18 17:01:40 -07002903 if (paramData == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002904 DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
Arun Menon906de572013-06-18 17:01:40 -07002905 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002906 }
Arun Menon906de572013-06-18 17:01:40 -07002907 if ((m_state != OMX_StateLoaded) &&
2908 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2909 (m_out_bEnabled == OMX_TRUE) &&
2910 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2911 (m_inp_bEnabled == OMX_TRUE)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002912 DEBUG_PRINT_ERROR("Set Param in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002913 return OMX_ErrorIncorrectStateOperation;
2914 }
Arun Menon906de572013-06-18 17:01:40 -07002915 switch ((unsigned long)paramIndex) {
2916 case OMX_IndexParamPortDefinition: {
2917 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2918 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2919 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2920 //been called.
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002921 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
Arun Menon906de572013-06-18 17:01:40 -07002922 (int)portDefn->format.video.nFrameHeight,
2923 (int)portDefn->format.video.nFrameWidth);
2924 if (OMX_DirOutput == portDefn->eDir) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002925 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
Arun Menon906de572013-06-18 17:01:40 -07002926 m_display_id = portDefn->format.video.pNativeWindow;
2927 unsigned int buffer_size;
Praveen Chavane78460c2013-12-06 23:16:04 -08002928 /* update output port resolution with client supplied dimensions
2929 in case scaling is enabled, else it follows input resolution set
2930 */
2931 if (is_down_scalar_enabled) {
2932 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07002933 portDefn->format.video.nFrameWidth,
2934 portDefn->format.video.nFrameHeight);
2935 if (portDefn->format.video.nFrameHeight != 0x0 &&
2936 portDefn->format.video.nFrameWidth != 0x0) {
2937 update_resolution(portDefn->format.video.nFrameWidth,
2938 portDefn->format.video.nFrameHeight,
2939 portDefn->format.video.nFrameWidth,
2940 portDefn->format.video.nFrameHeight);
2941 eRet = is_video_session_supported();
2942 if (eRet)
2943 break;
2944 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2945 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2946 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2947 fmt.fmt.pix_mp.pixelformat = capture_capability;
2948 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);
2949 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2950 if (ret) {
2951 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2952 eRet = OMX_ErrorUnsupportedSetting;
2953 } else
2954 eRet = get_buffer_req(&drv_ctx.op_buf);
2955 }
Praveen Chavane78460c2013-12-06 23:16:04 -08002956 }
Arun Menon906de572013-06-18 17:01:40 -07002957 if (!client_buffers.get_buffer_req(buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002958 DEBUG_PRINT_ERROR("Error in getting buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07002959 eRet = OMX_ErrorBadParameter;
2960 } else {
2961 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
2962 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
2963 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
2964 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
2965 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
2966 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
2967 drv_ctx.extradata_info.buffer_size;
2968 eRet = set_buffer_req(&drv_ctx.op_buf);
2969 if (eRet == OMX_ErrorNone)
2970 m_port_def = *portDefn;
2971 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07002972 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07002973 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
2974 portDefn->nBufferCountActual, portDefn->nBufferSize);
2975 eRet = OMX_ErrorBadParameter;
2976 }
2977 }
2978 } else if (OMX_DirInput == portDefn->eDir) {
2979 bool port_format_changed = false;
2980 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
2981 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
2982 // Frame rate only should be set if this is a "known value" or to
2983 // activate ts prediction logic (arbitrary mode only) sending input
2984 // timestamps with max value (LLONG_MAX).
2985 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
2986 portDefn->format.video.xFramerate >> 16);
2987 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
2988 drv_ctx.frame_rate.fps_denominator);
2989 if (!drv_ctx.frame_rate.fps_numerator) {
2990 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
2991 drv_ctx.frame_rate.fps_numerator = 30;
2992 }
2993 if (drv_ctx.frame_rate.fps_denominator)
2994 drv_ctx.frame_rate.fps_numerator = (int)
2995 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
2996 drv_ctx.frame_rate.fps_denominator = 1;
2997 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
2998 drv_ctx.frame_rate.fps_numerator;
2999 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
3000 frm_int, drv_ctx.frame_rate.fps_numerator /
3001 (float)drv_ctx.frame_rate.fps_denominator);
3002 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003003 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
Arun Menon906de572013-06-18 17:01:40 -07003004 if (drv_ctx.video_resolution.frame_height !=
3005 portDefn->format.video.nFrameHeight ||
3006 drv_ctx.video_resolution.frame_width !=
3007 portDefn->format.video.nFrameWidth) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003008 DEBUG_PRINT_LOW("SetParam IP: WxH(%lu x %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003009 portDefn->format.video.nFrameWidth,
3010 portDefn->format.video.nFrameHeight);
3011 port_format_changed = true;
Praveen Chavancf924182013-12-06 23:16:23 -08003012 OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
3013 OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
3014 if (frameHeight != 0x0 && frameWidth != 0x0) {
3015 if (m_smoothstreaming_mode &&
3016 ((frameWidth * frameHeight) <
3017 (m_smoothstreaming_width * m_smoothstreaming_height))) {
3018 frameWidth = m_smoothstreaming_width;
3019 frameHeight = m_smoothstreaming_height;
3020 DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
3021 frameWidth, frameHeight);
3022 }
3023 update_resolution(frameWidth, frameHeight,
3024 frameWidth, frameHeight);
Arun Menon906de572013-06-18 17:01:40 -07003025 eRet = is_video_session_supported();
3026 if (eRet)
3027 break;
3028 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3029 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3030 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3031 fmt.fmt.pix_mp.pixelformat = output_capability;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003032 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 -07003033 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3034 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003035 DEBUG_PRINT_ERROR("Set Resolution failed");
Arun Menon906de572013-06-18 17:01:40 -07003036 eRet = OMX_ErrorUnsupportedSetting;
3037 } else
3038 eRet = get_buffer_req(&drv_ctx.op_buf);
3039 }
3040 }
3041 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3042 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3043 port_format_changed = true;
3044 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3045 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3046 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3047 (~(buffer_prop->alignment - 1));
3048 eRet = set_buffer_req(buffer_prop);
3049 }
3050 if (false == port_format_changed) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003051 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
Arun Menon906de572013-06-18 17:01:40 -07003052 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3053 portDefn->nBufferCountActual, portDefn->nBufferSize);
3054 eRet = OMX_ErrorBadParameter;
3055 }
3056 } else if (portDefn->eDir == OMX_DirMax) {
3057 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3058 (int)portDefn->nPortIndex);
3059 eRet = OMX_ErrorBadPortIndex;
3060 }
3061 }
3062 break;
3063 case OMX_IndexParamVideoPortFormat: {
3064 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3065 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3066 int ret=0;
3067 struct v4l2_format fmt;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003068 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
Arun Menon906de572013-06-18 17:01:40 -07003069 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003070
Arun Menon906de572013-06-18 17:01:40 -07003071 if (1 == portFmt->nPortIndex) {
3072 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3073 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3074 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3075 fmt.fmt.pix_mp.pixelformat = capture_capability;
3076 enum vdec_output_fromat op_format;
3077 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3078 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
3079 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
3080 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
3081 else if (portFmt->eColorFormat ==
3082 (OMX_COLOR_FORMATTYPE)
3083 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3084 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3085 else
3086 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003087
Arun Menon906de572013-06-18 17:01:40 -07003088 if (eRet == OMX_ErrorNone) {
3089 drv_ctx.output_format = op_format;
3090 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3091 if (ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003092 DEBUG_PRINT_ERROR("Set output format failed");
Arun Menon906de572013-06-18 17:01:40 -07003093 eRet = OMX_ErrorUnsupportedSetting;
3094 /*TODO: How to handle this case */
3095 } else {
3096 eRet = get_buffer_req(&drv_ctx.op_buf);
3097 }
3098 }
3099 if (eRet == OMX_ErrorNone) {
3100 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003101 DEBUG_PRINT_ERROR("Set color format failed");
Arun Menon906de572013-06-18 17:01:40 -07003102 eRet = OMX_ErrorBadParameter;
3103 }
3104 }
3105 }
3106 }
3107 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003108
Arun Menon906de572013-06-18 17:01:40 -07003109 case OMX_QcomIndexPortDefn: {
3110 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3111 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003112 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu",
Arun Menon906de572013-06-18 17:01:40 -07003113 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003114
Arun Menon906de572013-06-18 17:01:40 -07003115 /* Input port */
3116 if (portFmt->nPortIndex == 0) {
3117 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3118 if (secure_mode) {
3119 arbitrary_bytes = false;
3120 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3121 eRet = OMX_ErrorUnsupportedSetting;
3122 } else {
3123 arbitrary_bytes = true;
3124 }
3125 } else if (portFmt->nFramePackingFormat ==
3126 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3127 arbitrary_bytes = false;
3128 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003129 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu",
Arun Menon906de572013-06-18 17:01:40 -07003130 portFmt->nFramePackingFormat);
3131 eRet = OMX_ErrorUnsupportedSetting;
3132 }
3133 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003134 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003135 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3136 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3137 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3138 m_out_mem_region_smi = OMX_TRUE;
3139 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003140 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003141 m_use_output_pmem = OMX_TRUE;
3142 }
3143 }
3144 }
3145 }
3146 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003147
Arun Menon906de572013-06-18 17:01:40 -07003148 case OMX_IndexParamStandardComponentRole: {
3149 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3150 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003151 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
Arun Menon906de572013-06-18 17:01:40 -07003152 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003153
Arun Menon906de572013-06-18 17:01:40 -07003154 if ((m_state == OMX_StateLoaded)&&
3155 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3156 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3157 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003158 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003159 return OMX_ErrorIncorrectStateOperation;
3160 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003161
Arun Menon906de572013-06-18 17:01:40 -07003162 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3163 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3164 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3165 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003166 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003167 eRet =OMX_ErrorUnsupportedSetting;
3168 }
3169 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3170 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3171 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3172 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003173 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003174 eRet = OMX_ErrorUnsupportedSetting;
3175 }
3176 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3177 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3178 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3179 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003180 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003181 eRet =OMX_ErrorUnsupportedSetting;
3182 }
3183 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3184 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3185 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3186 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003187 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003188 eRet = OMX_ErrorUnsupportedSetting;
3189 }
3190 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3191 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3192 ) {
3193 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3194 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3195 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003196 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003197 eRet =OMX_ErrorUnsupportedSetting;
3198 }
3199 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3200 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3201 ) {
3202 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3203 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3204 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003205 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003206 eRet =OMX_ErrorUnsupportedSetting;
3207 }
3208 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3209 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3210 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3211 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3212 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003213 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
Arun Menon906de572013-06-18 17:01:40 -07003214 eRet = OMX_ErrorUnsupportedSetting;
3215 }
3216 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003217 DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
Arun Menon906de572013-06-18 17:01:40 -07003218 eRet = OMX_ErrorInvalidComponentName;
3219 }
3220 break;
3221 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003222
Arun Menon906de572013-06-18 17:01:40 -07003223 case OMX_IndexParamPriorityMgmt: {
3224 if (m_state != OMX_StateLoaded) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003225 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003226 return OMX_ErrorIncorrectStateOperation;
3227 }
3228 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003229 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu",
Arun Menon906de572013-06-18 17:01:40 -07003230 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003231
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003232 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu",
Arun Menon906de572013-06-18 17:01:40 -07003233 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003234
Arun Menon906de572013-06-18 17:01:40 -07003235 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3236 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003237
Arun Menon906de572013-06-18 17:01:40 -07003238 break;
3239 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003240
Arun Menon906de572013-06-18 17:01:40 -07003241 case OMX_IndexParamCompBufferSupplier: {
3242 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003243 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
Arun Menon906de572013-06-18 17:01:40 -07003244 bufferSupplierType->eBufferSupplier);
3245 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3246 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003247
Arun Menon906de572013-06-18 17:01:40 -07003248 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003249
Arun Menon906de572013-06-18 17:01:40 -07003250 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003251
Arun Menon906de572013-06-18 17:01:40 -07003252 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003253
Arun Menon906de572013-06-18 17:01:40 -07003254 }
3255 case OMX_IndexParamVideoAvc: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003256 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
Arun Menon906de572013-06-18 17:01:40 -07003257 paramIndex);
3258 break;
3259 }
3260 case OMX_IndexParamVideoH263: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003261 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
Arun Menon906de572013-06-18 17:01:40 -07003262 paramIndex);
3263 break;
3264 }
3265 case OMX_IndexParamVideoMpeg4: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003266 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
Arun Menon906de572013-06-18 17:01:40 -07003267 paramIndex);
3268 break;
3269 }
3270 case OMX_IndexParamVideoMpeg2: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003271 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
Arun Menon906de572013-06-18 17:01:40 -07003272 paramIndex);
3273 break;
3274 }
3275 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3276 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3277 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3278 struct v4l2_control control;
3279 int pic_order,rc=0;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003280 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
Arun Menon906de572013-06-18 17:01:40 -07003281 pictureOrder->eOutputPictureOrder);
3282 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3283 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3284 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3285 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3286 time_stamp_dts.set_timestamp_reorder_mode(false);
3287 } else
3288 eRet = OMX_ErrorBadParameter;
3289 if (eRet == OMX_ErrorNone) {
3290 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3291 control.value = pic_order;
3292 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3293 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003294 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003295 eRet = OMX_ErrorUnsupportedSetting;
3296 }
3297 }
3298 break;
3299 }
3300 case OMX_QcomIndexParamConcealMBMapExtraData:
3301 if (!secure_mode)
3302 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3303 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3304 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003305 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003306 eRet = OMX_ErrorUnsupportedSetting;
3307 }
3308 break;
3309 case OMX_QcomIndexParamFrameInfoExtraData: {
3310 if (!secure_mode)
3311 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3312 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3313 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003314 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003315 eRet = OMX_ErrorUnsupportedSetting;
3316 }
3317 break;
3318 }
3319 case OMX_QcomIndexParamInterlaceExtraData:
3320 if (!secure_mode)
3321 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3322 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3323 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003324 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003325 eRet = OMX_ErrorUnsupportedSetting;
3326 }
3327 break;
3328 case OMX_QcomIndexParamH264TimeInfo:
3329 if (!secure_mode)
3330 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3331 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3332 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003333 DEBUG_PRINT_ERROR("secure mode setting not supported");
Arun Menon906de572013-06-18 17:01:40 -07003334 eRet = OMX_ErrorUnsupportedSetting;
3335 }
3336 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303337 case OMX_QcomIndexParamVideoFramePackingExtradata:
3338 if (!secure_mode)
3339 eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
3340 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3341 else {
3342 DEBUG_PRINT_ERROR("\n Setting extradata in secure mode is not supported");
3343 eRet = OMX_ErrorUnsupportedSetting;
3344 }
3345 break;
Arun Menon906de572013-06-18 17:01:40 -07003346 case OMX_QcomIndexParamVideoDivx: {
3347 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3348 }
3349 break;
3350 case OMX_QcomIndexPlatformPvt: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003351 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
Arun Menon906de572013-06-18 17:01:40 -07003352 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3353 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3354 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3355 eRet = OMX_ErrorUnsupportedSetting;
3356 } else {
3357 m_out_pvt_entry_pmem = OMX_TRUE;
3358 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003359 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
Arun Menon906de572013-06-18 17:01:40 -07003360 m_use_output_pmem = OMX_TRUE;
3361 }
3362 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003363
Arun Menon906de572013-06-18 17:01:40 -07003364 }
3365 break;
3366 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3367 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3368 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3369 struct v4l2_control control;
3370 int rc;
3371 drv_ctx.idr_only_decoding = 1;
3372 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3373 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3374 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3375 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003376 DEBUG_PRINT_ERROR("Set picture order failed");
Arun Menon906de572013-06-18 17:01:40 -07003377 eRet = OMX_ErrorUnsupportedSetting;
3378 } else {
3379 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3380 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3381 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3382 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003383 DEBUG_PRINT_ERROR("Sync frame setting failed");
Arun Menon906de572013-06-18 17:01:40 -07003384 eRet = OMX_ErrorUnsupportedSetting;
3385 }
3386 /*Setting sync frame decoding on driver might change buffer
3387 * requirements so update them here*/
3388 if (get_buffer_req(&drv_ctx.ip_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003389 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003390 eRet = OMX_ErrorUnsupportedSetting;
3391 }
3392 if (get_buffer_req(&drv_ctx.op_buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003393 DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
Arun Menon906de572013-06-18 17:01:40 -07003394 eRet = OMX_ErrorUnsupportedSetting;
3395 }
3396 }
3397 }
3398 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003399
Arun Menon906de572013-06-18 17:01:40 -07003400 case OMX_QcomIndexParamIndexExtraDataType: {
3401 if (!secure_mode) {
3402 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3403 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3404 (extradataIndexType->bEnabled == OMX_TRUE) &&
3405 (extradataIndexType->nPortIndex == 1)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003406 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
Arun Menon906de572013-06-18 17:01:40 -07003407 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003408
Arun Menon906de572013-06-18 17:01:40 -07003409 }
3410 }
3411 }
3412 break;
3413 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003414#ifndef SMOOTH_STREAMING_DISABLED
Praveen Chavancf924182013-12-06 23:16:23 -08003415 eRet = enable_smoothstreaming();
Arun Menonbc0922f2013-06-24 13:02:15 -07003416#else
Arun Menon906de572013-06-18 17:01:40 -07003417 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003418#endif
Arun Menon906de572013-06-18 17:01:40 -07003419 }
3420 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003421#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003422 /* Need to allow following two set_parameters even in Idle
3423 * state. This is ANDROID architecture which is not in sync
3424 * with openmax standard. */
3425 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3426 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3427 if (enableNativeBuffers) {
3428 m_enable_android_native_buffers = enableNativeBuffers->enable;
3429 }
3430 }
3431 break;
3432 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3433 eRet = use_android_native_buffer(hComp, paramData);
3434 }
3435 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003436#endif
Arun Menon906de572013-06-18 17:01:40 -07003437 case OMX_QcomIndexParamEnableTimeStampReorder: {
3438 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3439 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3440 if (reorder->bEnable == OMX_TRUE) {
3441 frm_int =0;
3442 time_stamp_dts.set_timestamp_reorder_mode(true);
3443 } else
3444 time_stamp_dts.set_timestamp_reorder_mode(false);
3445 } else {
3446 time_stamp_dts.set_timestamp_reorder_mode(false);
3447 if (reorder->bEnable == OMX_TRUE) {
3448 eRet = OMX_ErrorUnsupportedSetting;
3449 }
3450 }
3451 }
3452 break;
3453 case OMX_IndexParamVideoProfileLevelCurrent: {
3454 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3455 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3456 if (pParam) {
3457 m_profile_lvl.eProfile = pParam->eProfile;
3458 m_profile_lvl.eLevel = pParam->eLevel;
3459 }
3460 break;
Arun Menon888aa852013-05-30 11:24:42 -07003461
Arun Menon906de572013-06-18 17:01:40 -07003462 }
Arun Menone5652482013-08-04 13:33:05 -07003463 case OMX_QcomIndexParamVideoMetaBufferMode:
3464 {
3465 StoreMetaDataInBuffersParams *metabuffer =
3466 (StoreMetaDataInBuffersParams *)paramData;
3467 if (!metabuffer) {
3468 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3469 eRet = OMX_ErrorBadParameter;
3470 break;
3471 }
3472 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3473 //set property dynamic buffer mode to driver.
3474 struct v4l2_control control;
3475 struct v4l2_format fmt;
3476 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3477 if (metabuffer->bStoreMetaData == true) {
3478 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3479 } else {
3480 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3481 }
3482 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3483 if (!rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003484 DEBUG_PRINT_HIGH("%s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003485 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003486 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003487 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003488 DEBUG_PRINT_ERROR("Failed to %s buffer mode",
Arun Menone5652482013-08-04 13:33:05 -07003489 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3490 eRet = OMX_ErrorUnsupportedSetting;
3491 }
3492 } else {
3493 DEBUG_PRINT_ERROR(
Praveen Chavancf924182013-12-06 23:16:23 -08003494 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
Arun Menone5652482013-08-04 13:33:05 -07003495 metabuffer->nPortIndex);
3496 eRet = OMX_ErrorUnsupportedSetting;
3497 }
3498 break;
3499 }
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003500 case OMX_QcomIndexParamVideoDownScalar: {
3501 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3502 struct v4l2_control control;
3503 int rc;
3504 if (pParam) {
3505 is_down_scalar_enabled = pParam->bEnable;
3506 if (is_down_scalar_enabled) {
3507 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3508 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3509 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3510 pParam->bEnable);
3511 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3512 if (rc < 0) {
3513 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3514 eRet = OMX_ErrorUnsupportedSetting;
3515 }
3516 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3517 control.value = 1;
3518 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3519 if (rc < 0) {
3520 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3521 eRet = OMX_ErrorUnsupportedSetting;
3522 }
3523 }
3524 }
3525 break;
3526 }
Praveen Chavancf924182013-12-06 23:16:23 -08003527#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
3528 case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
3529 {
3530 DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
3531 PrepareForAdaptivePlaybackParams* pParams =
3532 (PrepareForAdaptivePlaybackParams *) paramData;
3533 if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3534 if (!pParams->bEnable) {
3535 return OMX_ErrorNone;
3536 }
3537 if (pParams->nMaxFrameWidth > kMaxSmoothStreamingWidth
3538 || pParams->nMaxFrameHeight > kMaxSmoothStreamingHeight) {
3539 DEBUG_PRINT_ERROR(
3540 "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
3541 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
3542 kMaxSmoothStreamingWidth, kMaxSmoothStreamingHeight);
3543 eRet = OMX_ErrorBadParameter;
3544 } else {
3545 eRet = enable_smoothstreaming();
3546 if (eRet != OMX_ErrorNone) {
3547 DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver.");
3548 eRet = OMX_ErrorHardware;
3549 } else {
3550 DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
3551 pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
3552 m_smoothstreaming_mode = true;
3553 m_smoothstreaming_width = pParams->nMaxFrameWidth;
3554 m_smoothstreaming_height = pParams->nMaxFrameHeight;
3555 }
3556 }
3557 } else {
3558 DEBUG_PRINT_ERROR(
3559 "Prepare for adaptive playback supported only on output port");
3560 eRet = OMX_ErrorBadParameter;
3561 }
3562 break;
3563 }
3564
3565#endif
Arun Menon906de572013-06-18 17:01:40 -07003566 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003567 DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
Arun Menon906de572013-06-18 17:01:40 -07003568 eRet = OMX_ErrorUnsupportedIndex;
3569 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003570 }
Arun Menon906de572013-06-18 17:01:40 -07003571 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003572}
3573
3574/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003575 FUNCTION
3576 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003577
Arun Menon906de572013-06-18 17:01:40 -07003578 DESCRIPTION
3579 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003580
Arun Menon906de572013-06-18 17:01:40 -07003581 PARAMETERS
3582 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003583
Arun Menon906de572013-06-18 17:01:40 -07003584 RETURN VALUE
3585 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003586
Arun Menon906de572013-06-18 17:01:40 -07003587 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003588OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003589 OMX_IN OMX_INDEXTYPE configIndex,
3590 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003591{
Arun Menon906de572013-06-18 17:01:40 -07003592 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003593
Arun Menon906de572013-06-18 17:01:40 -07003594 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003595 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003596 return OMX_ErrorInvalidState;
3597 }
Arun Menon906de572013-06-18 17:01:40 -07003598
3599 switch ((unsigned long)configIndex) {
3600 case OMX_QcomIndexConfigInterlaced: {
3601 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3602 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3603 if (configFmt->nPortIndex == 1) {
3604 if (configFmt->nIndex == 0) {
3605 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3606 } else if (configFmt->nIndex == 1) {
3607 configFmt->eInterlaceType =
3608 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3609 } else if (configFmt->nIndex == 2) {
3610 configFmt->eInterlaceType =
3611 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3612 } else {
3613 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003614 " NoMore Interlaced formats");
Arun Menon906de572013-06-18 17:01:40 -07003615 eRet = OMX_ErrorNoMore;
3616 }
3617
3618 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003619 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
Arun Menon906de572013-06-18 17:01:40 -07003620 (int)configFmt->nPortIndex);
3621 eRet = OMX_ErrorBadPortIndex;
3622 }
3623 break;
3624 }
3625 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3626 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3627 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3628 decoderinstances->nNumOfInstances = 16;
3629 /*TODO: How to handle this case */
3630 break;
3631 }
3632 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3633 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3634 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3635 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303636 memcpy(configFmt, &m_frame_pack_arrangement,
3637 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
Arun Menon906de572013-06-18 17:01:40 -07003638 } else {
3639 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3640 }
3641 break;
3642 }
3643 case OMX_IndexConfigCommonOutputCrop: {
3644 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3645 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3646 break;
3647 }
3648 default: {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003649 DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
Arun Menon906de572013-06-18 17:01:40 -07003650 eRet = OMX_ErrorBadParameter;
3651 }
3652
Shalaj Jain273b3e02012-06-22 19:08:03 -07003653 }
Arun Menon906de572013-06-18 17:01:40 -07003654
3655 return eRet;
3656}
3657
3658/* ======================================================================
3659 FUNCTION
3660 omx_vdec::SetConfig
3661
3662 DESCRIPTION
3663 OMX Set Config method implementation
3664
3665 PARAMETERS
3666 <TBD>.
3667
3668 RETURN VALUE
3669 OMX Error None if successful.
3670 ========================================================================== */
3671OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3672 OMX_IN OMX_INDEXTYPE configIndex,
3673 OMX_IN OMX_PTR configData)
3674{
3675 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003676 DEBUG_PRINT_ERROR("Get Config in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003677 return OMX_ErrorInvalidState;
3678 }
3679
3680 OMX_ERRORTYPE ret = OMX_ErrorNone;
3681 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3682
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003683 DEBUG_PRINT_LOW("Set Config Called");
Arun Menon906de572013-06-18 17:01:40 -07003684
3685 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3686 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003687 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
Arun Menon906de572013-06-18 17:01:40 -07003688 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003689 DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
Arun Menon906de572013-06-18 17:01:40 -07003690 OMX_U32 extra_size;
3691 // Parsing done here for the AVC atom is definitely not generic
3692 // Currently this piece of code is working, but certainly
3693 // not tested with all .mp4 files.
3694 // Incase of failure, we might need to revisit this
3695 // for a generic piece of code.
3696
3697 // Retrieve size of NAL length field
3698 // byte #4 contains the size of NAL lenght field
3699 nal_length = (config->pData[4] & 0x03) + 1;
3700
3701 extra_size = 0;
3702 if (nal_length > 2) {
3703 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3704 extra_size = (nal_length - 2) * 2;
3705 }
3706
3707 // SPS starts from byte #6
3708 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3709 OMX_U8 *pDestBuf;
3710 m_vendor_config.nPortIndex = config->nPortIndex;
3711
3712 // minus 6 --> SPS starts from byte #6
3713 // minus 1 --> picture param set byte to be ignored from avcatom
3714 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3715 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3716 OMX_U32 len;
3717 OMX_U8 index = 0;
3718 // case where SPS+PPS is sent as part of set_config
3719 pDestBuf = m_vendor_config.pData;
3720
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003721 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]",
Arun Menon906de572013-06-18 17:01:40 -07003722 m_vendor_config.nPortIndex,
3723 m_vendor_config.nDataSize,
3724 m_vendor_config.pData);
3725 while (index < 2) {
3726 uint8 *psize;
3727 len = *pSrcBuf;
3728 len = len << 8;
3729 len |= *(pSrcBuf + 1);
3730 psize = (uint8 *) & len;
3731 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3732 for (unsigned int i = 0; i < nal_length; i++) {
3733 pDestBuf[i] = psize[nal_length - 1 - i];
3734 }
3735 //memcpy(pDestBuf,pSrcBuf,(len+2));
3736 pDestBuf += len + nal_length;
3737 pSrcBuf += len + 2;
3738 index++;
3739 pSrcBuf++; // skip picture param set
3740 len = 0;
3741 }
3742 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3743 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3744 m_vendor_config.nPortIndex = config->nPortIndex;
3745 m_vendor_config.nDataSize = config->nDataSize;
3746 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3747 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3748 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3749 if (m_vendor_config.pData) {
3750 free(m_vendor_config.pData);
3751 m_vendor_config.pData = NULL;
3752 m_vendor_config.nDataSize = 0;
3753 }
3754
3755 if (((*((OMX_U32 *) config->pData)) &
3756 VC1_SP_MP_START_CODE_MASK) ==
3757 VC1_SP_MP_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003758 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
Arun Menon906de572013-06-18 17:01:40 -07003759 m_vendor_config.nPortIndex = config->nPortIndex;
3760 m_vendor_config.nDataSize = config->nDataSize;
3761 m_vendor_config.pData =
3762 (OMX_U8 *) malloc(config->nDataSize);
3763 memcpy(m_vendor_config.pData, config->pData,
3764 config->nDataSize);
3765 m_vc1_profile = VC1_SP_MP_RCV;
3766 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003767 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
Arun Menon906de572013-06-18 17:01:40 -07003768 m_vendor_config.nPortIndex = config->nPortIndex;
3769 m_vendor_config.nDataSize = config->nDataSize;
3770 m_vendor_config.pData =
3771 (OMX_U8 *) malloc((config->nDataSize));
3772 memcpy(m_vendor_config.pData, config->pData,
3773 config->nDataSize);
3774 m_vc1_profile = VC1_AP;
3775 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003776 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
Arun Menon906de572013-06-18 17:01:40 -07003777 m_vendor_config.nPortIndex = config->nPortIndex;
3778 m_vendor_config.nDataSize = config->nDataSize;
3779 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3780 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3781 m_vc1_profile = VC1_SP_MP_RCV;
3782 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003783 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
Arun Menon906de572013-06-18 17:01:40 -07003784 }
3785 }
3786 return ret;
3787 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3788 struct v4l2_control temp;
3789 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3790
3791 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3792 switch (pNal->nNaluBytes) {
3793 case 0:
3794 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3795 break;
3796 case 2:
3797 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3798 break;
3799 case 4:
3800 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3801 break;
3802 default:
3803 return OMX_ErrorUnsupportedSetting;
3804 }
3805
3806 if (!arbitrary_bytes) {
3807 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3808 * with start code, so only need to notify driver in frame by frame mode */
3809 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3810 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3811 return OMX_ErrorHardware;
3812 }
3813 }
3814
3815 nal_length = pNal->nNaluBytes;
3816 m_frame_parser.init_nal_length(nal_length);
3817
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003818 DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
Arun Menon906de572013-06-18 17:01:40 -07003819 return ret;
Surajit Podderd2644d52013-08-28 17:59:06 +05303820 } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
Arun Menon906de572013-06-18 17:01:40 -07003821 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
Surajit Podderd2644d52013-08-28 17:59:06 +05303822 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %lu", config->nFps);
Arun Menon906de572013-06-18 17:01:40 -07003823
3824 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3825 if (config->bEnabled) {
3826 if ((config->nFps >> 16) > 0) {
Surajit Podderd2644d52013-08-28 17:59:06 +05303827 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %lu",
Arun Menon906de572013-06-18 17:01:40 -07003828 config->nFps >> 16);
3829 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3830 drv_ctx.frame_rate.fps_denominator);
3831
3832 if (!drv_ctx.frame_rate.fps_numerator) {
3833 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3834 drv_ctx.frame_rate.fps_numerator = 30;
3835 }
3836
3837 if (drv_ctx.frame_rate.fps_denominator) {
3838 drv_ctx.frame_rate.fps_numerator = (int)
3839 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3840 }
3841
3842 drv_ctx.frame_rate.fps_denominator = 1;
3843 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3844 drv_ctx.frame_rate.fps_numerator;
3845
3846 struct v4l2_outputparm oparm;
3847 /*XXX: we're providing timing info as seconds per frame rather than frames
3848 * per second.*/
3849 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3850 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3851
3852 struct v4l2_streamparm sparm;
3853 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3854 sparm.parm.output = oparm;
3855 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3856 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3857 performance might be affected");
3858 ret = OMX_ErrorHardware;
3859 }
3860 client_set_fps = true;
3861 } else {
3862 DEBUG_PRINT_ERROR("Frame rate not supported.");
3863 ret = OMX_ErrorUnsupportedSetting;
3864 }
3865 } else {
3866 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3867 client_set_fps = false;
3868 }
3869 } else {
3870 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3871 (int)config->nPortIndex);
3872 ret = OMX_ErrorBadPortIndex;
3873 }
3874
3875 return ret;
3876 }
3877
3878 return OMX_ErrorNotImplemented;
3879}
3880
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303881#define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
3882
Arun Menon906de572013-06-18 17:01:40 -07003883/* ======================================================================
3884 FUNCTION
3885 omx_vdec::GetExtensionIndex
3886
3887 DESCRIPTION
3888 OMX GetExtensionIndex method implementaion. <TBD>
3889
3890 PARAMETERS
3891 <TBD>.
3892
3893 RETURN VALUE
3894 OMX Error None if everything successful.
3895
3896 ========================================================================== */
3897OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3898 OMX_IN OMX_STRING paramName,
3899 OMX_OUT OMX_INDEXTYPE* indexType)
3900{
3901 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003902 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07003903 return OMX_ErrorInvalidState;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303904 } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
Arun Menon906de572013-06-18 17:01:40 -07003905 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303906 } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003907 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303908 } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
3909 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
3910 } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
3911 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003912 }
3913#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303914 else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003915 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303916 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003917 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303918 } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003919 DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003920 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303921 } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003922 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3923 }
3924#endif
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05303925 else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
Arun Menone5652482013-08-04 13:33:05 -07003926 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
3927 }
Praveen Chavancf924182013-12-06 23:16:23 -08003928#if ADAPTIVE_PLAYBACK_SUPPORTED
3929 else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
3930 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
3931 }
3932#endif
Arun Menon906de572013-06-18 17:01:40 -07003933 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003934 DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003935 return OMX_ErrorNotImplemented;
3936 }
3937 return OMX_ErrorNone;
3938}
3939
3940/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003941 FUNCTION
3942 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07003943
Arun Menon906de572013-06-18 17:01:40 -07003944 DESCRIPTION
3945 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003946
Arun Menon906de572013-06-18 17:01:40 -07003947 PARAMETERS
3948 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003949
Arun Menon906de572013-06-18 17:01:40 -07003950 RETURN VALUE
3951 Error None if everything is successful.
3952 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003953OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003954 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003955{
Arun Menon906de572013-06-18 17:01:40 -07003956 *state = m_state;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003957 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
Arun Menon906de572013-06-18 17:01:40 -07003958 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003959}
3960
3961/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003962 FUNCTION
3963 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07003964
Arun Menon906de572013-06-18 17:01:40 -07003965 DESCRIPTION
3966 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003967
Arun Menon906de572013-06-18 17:01:40 -07003968 PARAMETERS
3969 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003970
Arun Menon906de572013-06-18 17:01:40 -07003971 RETURN VALUE
3972 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003973
Arun Menon906de572013-06-18 17:01:40 -07003974 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003975OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003976 OMX_IN OMX_U32 port,
3977 OMX_IN OMX_HANDLETYPE peerComponent,
3978 OMX_IN OMX_U32 peerPort,
3979 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003980{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07003981 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
Arun Menon906de572013-06-18 17:01:40 -07003982 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003983}
3984
3985/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003986 FUNCTION
3987 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07003988
Arun Menon906de572013-06-18 17:01:40 -07003989 DESCRIPTION
3990 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07003991
Arun Menon906de572013-06-18 17:01:40 -07003992 PARAMETERS
3993 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003994
Arun Menon906de572013-06-18 17:01:40 -07003995 RETURN VALUE
3996 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07003997
Arun Menon906de572013-06-18 17:01:40 -07003998 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003999OMX_ERRORTYPE omx_vdec::allocate_extradata()
4000{
4001#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004002 if (drv_ctx.extradata_info.buffer_size) {
4003 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4004 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4005 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4006 free_ion_memory(&drv_ctx.extradata_info.ion);
4007 }
4008 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4009 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4010 drv_ctx.extradata_info.size, 4096,
4011 &drv_ctx.extradata_info.ion.ion_alloc_data,
4012 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4013 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004014 DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004015 return OMX_ErrorInsufficientResources;
4016 }
4017 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4018 drv_ctx.extradata_info.size,
4019 PROT_READ|PROT_WRITE, MAP_SHARED,
4020 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4021 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004022 DEBUG_PRINT_ERROR("Failed to map extradata memory");
Arun Menon906de572013-06-18 17:01:40 -07004023 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4024 free_ion_memory(&drv_ctx.extradata_info.ion);
4025 return OMX_ErrorInsufficientResources;
4026 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004027 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004028#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304029 if (!m_other_extradata) {
4030 m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
4031 if (!m_other_extradata) {
4032 DEBUG_PRINT_ERROR("Failed to alloc memory\n");
4033 return OMX_ErrorInsufficientResources;
4034 }
4035 }
Arun Menon906de572013-06-18 17:01:40 -07004036 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004037}
4038
Arun Menon906de572013-06-18 17:01:40 -07004039void omx_vdec::free_extradata()
4040{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004041#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004042 if (drv_ctx.extradata_info.uaddr) {
4043 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4044 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4045 free_ion_memory(&drv_ctx.extradata_info.ion);
4046 }
4047 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004048#endif
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304049 if (m_other_extradata) {
4050 free(m_other_extradata);
4051 m_other_extradata = NULL;
4052 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004053}
4054
Shalaj Jain273b3e02012-06-22 19:08:03 -07004055OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004056 OMX_IN OMX_HANDLETYPE hComp,
4057 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4058 OMX_IN OMX_U32 port,
4059 OMX_IN OMX_PTR appData,
4060 OMX_IN OMX_U32 bytes,
4061 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004062{
Arun Menon906de572013-06-18 17:01:40 -07004063 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4064 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4065 unsigned i= 0; // Temporary counter
4066 struct vdec_setbuffer_cmd setbuffers;
4067 OMX_PTR privateAppData = NULL;
4068 private_handle_t *handle = NULL;
4069 OMX_U8 *buff = buffer;
4070 struct v4l2_buffer buf;
4071 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4072 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004073
Arun Menon906de572013-06-18 17:01:40 -07004074 if (!m_out_mem_ptr) {
4075 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4076 eRet = allocate_output_headers();
4077 if (eRet == OMX_ErrorNone)
4078 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004079 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004080
Arun Menon906de572013-06-18 17:01:40 -07004081 if (eRet == OMX_ErrorNone) {
4082 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4083 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4084 break;
4085 }
4086 }
4087 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004088
Arun Menon906de572013-06-18 17:01:40 -07004089 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004090 DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
Arun Menon906de572013-06-18 17:01:40 -07004091 eRet = OMX_ErrorInsufficientResources;
4092 }
4093
Arun Menonbdb80b02013-08-12 17:45:54 -07004094 if (dynamic_buf_mode) {
4095 *bufferHdr = (m_out_mem_ptr + i );
4096 (*bufferHdr)->pBuffer = NULL;
4097 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4098 enum v4l2_buf_type buf_type;
4099 int rr = 0;
4100 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4101 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4102 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4103 return OMX_ErrorInsufficientResources;
4104 } else {
4105 streaming[CAPTURE_PORT] = true;
4106 DEBUG_PRINT_LOW("STREAMON Successful");
4107 }
4108 }
4109 BITMASK_SET(&m_out_bm_count,i);
4110 (*bufferHdr)->pAppPrivate = appData;
4111 (*bufferHdr)->pBuffer = buffer;
4112 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4113 return eRet;
4114 }
Arun Menon906de572013-06-18 17:01:40 -07004115 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004116#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004117 if (m_enable_android_native_buffers) {
4118 if (m_use_android_native_buffers) {
4119 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4120 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4121 handle = (private_handle_t *)nBuf->handle;
4122 privateAppData = params->pAppPrivate;
4123 } else {
4124 handle = (private_handle_t *)buff;
4125 privateAppData = appData;
4126 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004127
Arun Menon906de572013-06-18 17:01:40 -07004128 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4129 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4130 " expected %u, got %lu",
4131 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4132 return OMX_ErrorBadParameter;
4133 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004134
Arun Menon906de572013-06-18 17:01:40 -07004135 if (!m_use_android_native_buffers) {
4136 if (!secure_mode) {
4137 buff = (OMX_U8*)mmap(0, handle->size,
4138 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4139 if (buff == MAP_FAILED) {
4140 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4141 return OMX_ErrorInsufficientResources;
4142 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004143 }
4144 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004145#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004146 native_buffer[i].nativehandle = handle;
4147 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004148#endif
Arun Menon906de572013-06-18 17:01:40 -07004149 if (!handle) {
4150 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4151 return OMX_ErrorBadParameter;
4152 }
4153 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4154 drv_ctx.ptr_outputbuffer[i].offset = 0;
4155 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4156 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4157 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4158 } else
4159#endif
4160
4161 if (!ouput_egl_buffers && !m_use_output_pmem) {
4162#ifdef USE_ION
4163 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4164 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4165 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4166 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4167 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004168 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 -07004169 return OMX_ErrorInsufficientResources;
4170 }
4171 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4172 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4173#else
4174 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4175 open (MEM_DEVICE,O_RDWR);
4176
4177 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004178 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004179 return OMX_ErrorInsufficientResources;
4180 }
4181
4182 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4183 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4184 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4185 open (MEM_DEVICE,O_RDWR);
4186 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004187 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07004188 return OMX_ErrorInsufficientResources;
4189 }
4190 }
4191
4192 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4193 drv_ctx.op_buf.buffer_size,
4194 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004195 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004196 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4197 return OMX_ErrorInsufficientResources;
4198 }
4199#endif
4200 if (!secure_mode) {
4201 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4202 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4203 PROT_READ|PROT_WRITE, MAP_SHARED,
4204 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4205 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4206 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4207#ifdef USE_ION
4208 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4209#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004210 DEBUG_PRINT_ERROR("Unable to mmap output buffer");
Arun Menon906de572013-06-18 17:01:40 -07004211 return OMX_ErrorInsufficientResources;
4212 }
4213 }
4214 drv_ctx.ptr_outputbuffer[i].offset = 0;
4215 privateAppData = appData;
4216 } else {
4217
4218 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4219 if (!appData || !bytes ) {
4220 if (!secure_mode && !buffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004221 DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
Arun Menon906de572013-06-18 17:01:40 -07004222 return OMX_ErrorBadParameter;
4223 }
4224 }
4225
4226 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4227 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4228 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4229 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4230 !pmem_list->nEntries ||
4231 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004232 DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
Arun Menon906de572013-06-18 17:01:40 -07004233 return OMX_ErrorBadParameter;
4234 }
4235 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4236 pmem_list->entryList->entry;
4237 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4238 pmem_info->pmem_fd);
4239 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4240 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4241 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4242 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4243 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4244 privateAppData = appData;
4245 }
4246 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4247 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05304248 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
4249 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
4250 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07004251
4252 *bufferHdr = (m_out_mem_ptr + i );
4253 if (secure_mode)
4254 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4255 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4256 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4257 sizeof (vdec_bufferpayload));
4258
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004259 DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
Arun Menon906de572013-06-18 17:01:40 -07004260 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4261 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4262
4263 buf.index = i;
4264 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4265 buf.memory = V4L2_MEMORY_USERPTR;
4266 plane[0].length = drv_ctx.op_buf.buffer_size;
4267 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4268 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4269 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4270 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4271 plane[0].data_offset = 0;
4272 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4273 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4274 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4275 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4276#ifdef USE_ION
4277 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4278#endif
4279 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4280 plane[extra_idx].data_offset = 0;
4281 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004282 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004283 return OMX_ErrorBadParameter;
4284 }
Arun Menon906de572013-06-18 17:01:40 -07004285 buf.m.planes = plane;
4286 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004287
Arun Menon906de572013-06-18 17:01:40 -07004288 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004289 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004290 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004291 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004292 }
4293
Arun Menon906de572013-06-18 17:01:40 -07004294 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4295 enum v4l2_buf_type buf_type;
4296 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4297 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4298 return OMX_ErrorInsufficientResources;
4299 } else {
4300 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004301 DEBUG_PRINT_LOW("STREAMON Successful");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004302 }
4303 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004304
Arun Menon906de572013-06-18 17:01:40 -07004305 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4306 if (m_enable_android_native_buffers) {
4307 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4308 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4309 } else {
4310 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004311 }
Arun Menon906de572013-06-18 17:01:40 -07004312 (*bufferHdr)->pAppPrivate = privateAppData;
4313 BITMASK_SET(&m_out_bm_count,i);
4314 }
4315 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004316}
4317
4318/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004319 FUNCTION
4320 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004321
Arun Menon906de572013-06-18 17:01:40 -07004322 DESCRIPTION
4323 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004324
Arun Menon906de572013-06-18 17:01:40 -07004325 PARAMETERS
4326 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004327
Arun Menon906de572013-06-18 17:01:40 -07004328 RETURN VALUE
4329 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004330
Arun Menon906de572013-06-18 17:01:40 -07004331 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004332OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004333 OMX_IN OMX_HANDLETYPE hComp,
4334 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4335 OMX_IN OMX_U32 port,
4336 OMX_IN OMX_PTR appData,
4337 OMX_IN OMX_U32 bytes,
4338 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004339{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004340 DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
Arun Menon906de572013-06-18 17:01:40 -07004341 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4342 if (!m_inp_heap_ptr)
4343 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4344 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4345 drv_ctx.ip_buf.actualcount);
4346 if (!m_phdr_pmem_ptr)
4347 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4348 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4349 drv_ctx.ip_buf.actualcount);
4350 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4351 DEBUG_PRINT_ERROR("Insufficent memory");
4352 eRet = OMX_ErrorInsufficientResources;
4353 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4354 input_use_buffer = true;
4355 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4356 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4357 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4358 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4359 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4360 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4361 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4362 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004363 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 -07004364 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4365 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004366 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004367 return OMX_ErrorInsufficientResources;
4368 }
4369 m_in_alloc_cnt++;
4370 } else {
4371 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4372 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004373 }
Arun Menon906de572013-06-18 17:01:40 -07004374 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004375}
4376
4377/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004378 FUNCTION
4379 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004380
Arun Menon906de572013-06-18 17:01:40 -07004381 DESCRIPTION
4382 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004383
Arun Menon906de572013-06-18 17:01:40 -07004384 PARAMETERS
4385 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004386
Arun Menon906de572013-06-18 17:01:40 -07004387 RETURN VALUE
4388 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004389
Arun Menon906de572013-06-18 17:01:40 -07004390 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004391OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004392 OMX_IN OMX_HANDLETYPE hComp,
4393 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4394 OMX_IN OMX_U32 port,
4395 OMX_IN OMX_PTR appData,
4396 OMX_IN OMX_U32 bytes,
4397 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004398{
Arun Menon906de572013-06-18 17:01:40 -07004399 OMX_ERRORTYPE error = OMX_ErrorNone;
4400 struct vdec_setbuffer_cmd setbuffers;
4401
4402 if (bufferHdr == NULL || bytes == 0) {
4403 if (!secure_mode && buffer == NULL) {
4404 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4405 return OMX_ErrorBadParameter;
4406 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004407 }
Arun Menon906de572013-06-18 17:01:40 -07004408 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004409 DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07004410 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004411 }
Arun Menon906de572013-06-18 17:01:40 -07004412 if (port == OMX_CORE_INPUT_PORT_INDEX)
4413 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4414 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4415 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4416 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004417 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07004418 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004419 }
Arun Menon906de572013-06-18 17:01:40 -07004420 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4421 if (error == OMX_ErrorNone) {
4422 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4423 // Send the callback now
4424 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4425 post_event(OMX_CommandStateSet,OMX_StateIdle,
4426 OMX_COMPONENT_GENERATE_EVENT);
4427 }
4428 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4429 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4430 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4431 post_event(OMX_CommandPortEnable,
4432 OMX_CORE_INPUT_PORT_INDEX,
4433 OMX_COMPONENT_GENERATE_EVENT);
4434 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4435 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4436 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4437 post_event(OMX_CommandPortEnable,
4438 OMX_CORE_OUTPUT_PORT_INDEX,
4439 OMX_COMPONENT_GENERATE_EVENT);
4440 }
4441 }
4442 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004443}
4444
4445OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004446 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004447{
Arun Menon906de572013-06-18 17:01:40 -07004448 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4449 if (m_inp_heap_ptr[bufferindex].pBuffer)
4450 free(m_inp_heap_ptr[bufferindex].pBuffer);
4451 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4452 }
4453 if (pmem_bufferHdr)
4454 free_input_buffer(pmem_bufferHdr);
4455 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004456}
4457
4458OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4459{
Arun Menon906de572013-06-18 17:01:40 -07004460 unsigned int index = 0;
4461 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4462 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004463 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004464
Arun Menon906de572013-06-18 17:01:40 -07004465 index = bufferHdr - m_inp_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004466 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004467
4468 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004469 DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
Arun Menon906de572013-06-18 17:01:40 -07004470 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4471 struct vdec_setbuffer_cmd setbuffers;
4472 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4473 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4474 sizeof (vdec_bufferpayload));
4475 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004476 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
Arun Menon906de572013-06-18 17:01:40 -07004477 drv_ctx.ptr_inputbuffer[index].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004478 DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004479 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4480 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4481 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4482 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4483 }
4484 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4485 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4486 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4487 free(m_desc_buffer_ptr[index].buf_addr);
4488 m_desc_buffer_ptr[index].buf_addr = NULL;
4489 m_desc_buffer_ptr[index].desc_data_size = 0;
4490 }
4491#ifdef USE_ION
4492 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4493#endif
4494 }
4495 }
4496
4497 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004498}
4499
4500OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4501{
Arun Menon906de572013-06-18 17:01:40 -07004502 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004503
Arun Menon906de572013-06-18 17:01:40 -07004504 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4505 return OMX_ErrorBadParameter;
4506 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004507
Arun Menon906de572013-06-18 17:01:40 -07004508 index = bufferHdr - m_out_mem_ptr;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004509 DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004510
Arun Menon906de572013-06-18 17:01:40 -07004511 if (index < drv_ctx.op_buf.actualcount
4512 && drv_ctx.ptr_outputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004513 DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
Arun Menon906de572013-06-18 17:01:40 -07004514 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004515
Arun Menon906de572013-06-18 17:01:40 -07004516 struct vdec_setbuffer_cmd setbuffers;
4517 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4518 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4519 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004520#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004521 if (m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004522 if (!secure_mode) {
Arun Menon906de572013-06-18 17:01:40 -07004523 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4524 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4525 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4526 }
Praveen Chavan212671f2013-04-05 20:00:42 -07004527 }
Arun Menon906de572013-06-18 17:01:40 -07004528 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4529 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004530#endif
Arun Menon906de572013-06-18 17:01:40 -07004531 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4532 if (!secure_mode) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004533 DEBUG_PRINT_LOW("unmap the output buffer fd = %d",
Arun Menon906de572013-06-18 17:01:40 -07004534 drv_ctx.ptr_outputbuffer[0].pmem_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004535 DEBUG_PRINT_LOW("unmap the ouput buffer size=%d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07004536 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4537 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4538 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4539 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4540 }
4541 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4542 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004543#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004544 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004545#endif
Arun Menon906de572013-06-18 17:01:40 -07004546 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004547#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004548 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004549#endif
Arun Menon906de572013-06-18 17:01:40 -07004550 if (release_output_done()) {
4551 free_extradata();
4552 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004553 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004554
Arun Menon906de572013-06-18 17:01:40 -07004555 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004556
4557}
4558
4559OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004560 OMX_BUFFERHEADERTYPE **bufferHdr,
4561 OMX_U32 port,
4562 OMX_PTR appData,
4563 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004564{
Arun Menon906de572013-06-18 17:01:40 -07004565 OMX_BUFFERHEADERTYPE *input = NULL;
4566 unsigned char *buf_addr = NULL;
4567 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4568 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004569
Arun Menon906de572013-06-18 17:01:40 -07004570 /* Sanity Check*/
4571 if (bufferHdr == NULL) {
4572 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004573 }
4574
Arun Menon906de572013-06-18 17:01:40 -07004575 if (m_inp_heap_ptr == NULL) {
4576 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4577 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4578 drv_ctx.ip_buf.actualcount);
4579 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4580 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4581 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004582
Arun Menon906de572013-06-18 17:01:40 -07004583 if (m_inp_heap_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004584 DEBUG_PRINT_ERROR("m_inp_heap_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07004585 return OMX_ErrorInsufficientResources;
4586 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004587 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004588
Arun Menon906de572013-06-18 17:01:40 -07004589 /*Find a Free index*/
4590 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4591 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004592 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004593 break;
4594 }
4595 }
4596
4597 if (i < drv_ctx.ip_buf.actualcount) {
4598 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4599
4600 if (buf_addr == NULL) {
4601 return OMX_ErrorInsufficientResources;
4602 }
4603
4604 *bufferHdr = (m_inp_heap_ptr + i);
4605 input = *bufferHdr;
4606 BITMASK_SET(&m_heap_inp_bm_count,i);
4607
4608 input->pBuffer = (OMX_U8 *)buf_addr;
4609 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4610 input->nVersion.nVersion = OMX_SPEC_VERSION;
4611 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4612 input->pAppPrivate = appData;
4613 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004614 DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
Arun Menon906de572013-06-18 17:01:40 -07004615 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004616 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Arun Menon906de572013-06-18 17:01:40 -07004617 /*Add the Buffers to freeq*/
4618 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4619 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004620 DEBUG_PRINT_ERROR("ERROR:Free_q is full");
Arun Menon906de572013-06-18 17:01:40 -07004621 return OMX_ErrorInsufficientResources;
4622 }
4623 } else {
4624 return OMX_ErrorBadParameter;
4625 }
4626
4627 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004628
4629}
4630
4631
4632/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004633 FUNCTION
4634 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004635
Arun Menon906de572013-06-18 17:01:40 -07004636 DESCRIPTION
4637 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004638
Arun Menon906de572013-06-18 17:01:40 -07004639 PARAMETERS
4640 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004641
Arun Menon906de572013-06-18 17:01:40 -07004642 RETURN VALUE
4643 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004644
Arun Menon906de572013-06-18 17:01:40 -07004645 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004646OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004647 OMX_IN OMX_HANDLETYPE hComp,
4648 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4649 OMX_IN OMX_U32 port,
4650 OMX_IN OMX_PTR appData,
4651 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004652{
4653
Arun Menon906de572013-06-18 17:01:40 -07004654 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4655 struct vdec_setbuffer_cmd setbuffers;
4656 OMX_BUFFERHEADERTYPE *input = NULL;
4657 unsigned i = 0;
4658 unsigned char *buf_addr = NULL;
4659 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004660
Arun Menon906de572013-06-18 17:01:40 -07004661 if (bytes != drv_ctx.ip_buf.buffer_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004662 DEBUG_PRINT_LOW("Requested Size is wrong %lu epected is %d",
Arun Menon906de572013-06-18 17:01:40 -07004663 bytes, drv_ctx.ip_buf.buffer_size);
4664 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004665 }
4666
Arun Menon906de572013-06-18 17:01:40 -07004667 if (!m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004668 DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004669 drv_ctx.ip_buf.actualcount,
4670 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004671
Arun Menon906de572013-06-18 17:01:40 -07004672 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4673 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4674
4675 if (m_inp_mem_ptr == NULL) {
4676 return OMX_ErrorInsufficientResources;
4677 }
4678
4679 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4680 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4681
4682 if (drv_ctx.ptr_inputbuffer == NULL) {
4683 return OMX_ErrorInsufficientResources;
4684 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004685#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004686 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4687 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004688
Arun Menon906de572013-06-18 17:01:40 -07004689 if (drv_ctx.ip_buf_ion_info == NULL) {
4690 return OMX_ErrorInsufficientResources;
4691 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004692#endif
4693
Arun Menon906de572013-06-18 17:01:40 -07004694 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4695 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004696#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004697 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004698#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004699 }
4700 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004701
Arun Menon906de572013-06-18 17:01:40 -07004702 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4703 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004704 DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004705 break;
4706 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004707 }
Arun Menon906de572013-06-18 17:01:40 -07004708
4709 if (i < drv_ctx.ip_buf.actualcount) {
4710 struct v4l2_buffer buf;
4711 struct v4l2_plane plane;
4712 int rc;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004713 DEBUG_PRINT_LOW("Allocate input Buffer");
Arun Menon906de572013-06-18 17:01:40 -07004714#ifdef USE_ION
4715 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4716 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4717 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4718 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4719 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4720 return OMX_ErrorInsufficientResources;
4721 }
4722 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4723#else
4724 pmem_fd = open (MEM_DEVICE,O_RDWR);
4725
4726 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004727 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004728 return OMX_ErrorInsufficientResources;
4729 }
4730
4731 if (pmem_fd == 0) {
4732 pmem_fd = open (MEM_DEVICE,O_RDWR);
4733
4734 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004735 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004736 return OMX_ErrorInsufficientResources;
4737 }
4738 }
4739
4740 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4741 drv_ctx.ip_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004742 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004743 close(pmem_fd);
4744 return OMX_ErrorInsufficientResources;
4745 }
4746#endif
4747 if (!secure_mode) {
4748 buf_addr = (unsigned char *)mmap(NULL,
4749 drv_ctx.ip_buf.buffer_size,
4750 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4751
4752 if (buf_addr == MAP_FAILED) {
4753 close(pmem_fd);
4754#ifdef USE_ION
4755 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4756#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004757 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
Arun Menon906de572013-06-18 17:01:40 -07004758 return OMX_ErrorInsufficientResources;
4759 }
4760 }
4761 *bufferHdr = (m_inp_mem_ptr + i);
4762 if (secure_mode)
4763 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4764 else
4765 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4766 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4767 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4768 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4769 drv_ctx.ptr_inputbuffer [i].offset = 0;
4770
4771
4772 buf.index = i;
4773 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4774 buf.memory = V4L2_MEMORY_USERPTR;
4775 plane.bytesused = 0;
4776 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4777 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4778 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4779 plane.reserved[1] = 0;
4780 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4781 buf.m.planes = &plane;
4782 buf.length = 1;
4783
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004784 DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
Arun Menon906de572013-06-18 17:01:40 -07004785 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4786
4787 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4788
4789 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004790 DEBUG_PRINT_ERROR("Failed to prepare bufs");
Arun Menon906de572013-06-18 17:01:40 -07004791 /*TODO: How to handle this case */
4792 return OMX_ErrorInsufficientResources;
4793 }
4794
4795 input = *bufferHdr;
4796 BITMASK_SET(&m_inp_bm_count,i);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004797 DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07004798 if (secure_mode)
4799 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4800 else
4801 input->pBuffer = (OMX_U8 *)buf_addr;
4802 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4803 input->nVersion.nVersion = OMX_SPEC_VERSION;
4804 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4805 input->pAppPrivate = appData;
4806 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4807 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4808
4809 if (drv_ctx.disable_dmx) {
4810 eRet = allocate_desc_buffer(i);
4811 }
4812 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004813 DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07004814 eRet = OMX_ErrorInsufficientResources;
4815 }
4816 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004817}
4818
4819
4820/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004821 FUNCTION
4822 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004823
Arun Menon906de572013-06-18 17:01:40 -07004824 DESCRIPTION
4825 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004826
Arun Menon906de572013-06-18 17:01:40 -07004827 PARAMETERS
4828 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004829
Arun Menon906de572013-06-18 17:01:40 -07004830 RETURN VALUE
4831 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004832
Arun Menon906de572013-06-18 17:01:40 -07004833 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004834OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004835 OMX_IN OMX_HANDLETYPE hComp,
4836 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4837 OMX_IN OMX_U32 port,
4838 OMX_IN OMX_PTR appData,
4839 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004840{
Arun Menon906de572013-06-18 17:01:40 -07004841 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4842 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4843 unsigned i= 0; // Temporary counter
4844 struct vdec_setbuffer_cmd setbuffers;
4845 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004846#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004847 int ion_device_fd =-1;
4848 struct ion_allocation_data ion_alloc_data;
4849 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004850#endif
Arun Menon906de572013-06-18 17:01:40 -07004851 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004852 DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004853 drv_ctx.op_buf.actualcount,
4854 drv_ctx.op_buf.buffer_size);
4855 int nBufHdrSize = 0;
4856 int nPlatformEntrySize = 0;
4857 int nPlatformListSize = 0;
4858 int nPMEMInfoSize = 0;
4859 int pmem_fd = -1;
4860 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004861
Arun Menon906de572013-06-18 17:01:40 -07004862 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4863 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4864 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004865
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004866 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07004867 drv_ctx.op_buf.actualcount);
4868 nBufHdrSize = drv_ctx.op_buf.actualcount *
4869 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004870
Arun Menon906de572013-06-18 17:01:40 -07004871 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4872 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4873 nPlatformListSize = drv_ctx.op_buf.actualcount *
4874 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4875 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4876 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004877
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004878 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07004879 sizeof(OMX_BUFFERHEADERTYPE),
4880 nPMEMInfoSize,
4881 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004882 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07004883 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004884#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004885 ion_device_fd = alloc_map_ion_memory(
4886 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4887 drv_ctx.op_buf.alignment,
4888 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4889 if (ion_device_fd < 0) {
4890 return OMX_ErrorInsufficientResources;
4891 }
4892 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004893#else
Arun Menon906de572013-06-18 17:01:40 -07004894 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004895
Arun Menon906de572013-06-18 17:01:40 -07004896 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004897 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004898 drv_ctx.op_buf.buffer_size);
4899 return OMX_ErrorInsufficientResources;
4900 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004901
Arun Menon906de572013-06-18 17:01:40 -07004902 if (pmem_fd == 0) {
4903 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004904
Arun Menon906de572013-06-18 17:01:40 -07004905 if (pmem_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004906 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
Arun Menon906de572013-06-18 17:01:40 -07004907 drv_ctx.op_buf.buffer_size);
4908 return OMX_ErrorInsufficientResources;
4909 }
4910 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004911
Arun Menon906de572013-06-18 17:01:40 -07004912 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4913 drv_ctx.op_buf.actualcount,
4914 drv_ctx.op_buf.alignment)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004915 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
Arun Menon906de572013-06-18 17:01:40 -07004916 close(pmem_fd);
4917 return OMX_ErrorInsufficientResources;
4918 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004919#endif
Arun Menon906de572013-06-18 17:01:40 -07004920 if (!secure_mode) {
4921 pmem_baseaddress = (unsigned char *)mmap(NULL,
4922 (drv_ctx.op_buf.buffer_size *
4923 drv_ctx.op_buf.actualcount),
4924 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4925 if (pmem_baseaddress == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004926 DEBUG_PRINT_ERROR("MMAP failed for Size %d",
Arun Menon906de572013-06-18 17:01:40 -07004927 drv_ctx.op_buf.buffer_size);
4928 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004929#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004930 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004931#endif
Arun Menon906de572013-06-18 17:01:40 -07004932 return OMX_ErrorInsufficientResources;
4933 }
4934 }
4935 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4936 // Alloc mem for platform specific info
4937 char *pPtr=NULL;
4938 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4939 nPMEMInfoSize,1);
4940 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4941 calloc (sizeof(struct vdec_bufferpayload),
4942 drv_ctx.op_buf.actualcount);
4943 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4944 calloc (sizeof (struct vdec_output_frameinfo),
4945 drv_ctx.op_buf.actualcount);
4946#ifdef USE_ION
4947 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4948 calloc (sizeof(struct vdec_ion),
4949 drv_ctx.op_buf.actualcount);
4950#endif
4951
4952 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4953 && drv_ctx.ptr_respbuffer) {
4954 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4955 (drv_ctx.op_buf.buffer_size *
4956 drv_ctx.op_buf.actualcount);
4957 bufHdr = m_out_mem_ptr;
4958 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4959 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4960 (((char *) m_platform_list) + nPlatformListSize);
4961 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4962 (((char *) m_platform_entry) + nPlatformEntrySize);
4963 pPlatformList = m_platform_list;
4964 pPlatformEntry = m_platform_entry;
4965 pPMEMInfo = m_pmem_info;
4966
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004967 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07004968
4969 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004970 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
4971 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07004972 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4973 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4974 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4975 // Set the values when we determine the right HxW param
4976 bufHdr->nAllocLen = bytes;
4977 bufHdr->nFilledLen = 0;
4978 bufHdr->pAppPrivate = appData;
4979 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4980 // Platform specific PMEM Information
4981 // Initialize the Platform Entry
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07004982 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
Arun Menon906de572013-06-18 17:01:40 -07004983 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4984 pPlatformEntry->entry = pPMEMInfo;
4985 // Initialize the Platform List
4986 pPlatformList->nEntries = 1;
4987 pPlatformList->entryList = pPlatformEntry;
4988 // Keep pBuffer NULL till vdec is opened
4989 bufHdr->pBuffer = NULL;
4990 bufHdr->nOffset = 0;
4991
4992 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4993 pPMEMInfo->pmem_fd = 0;
4994 bufHdr->pPlatformPrivate = pPlatformList;
4995
4996 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
4997 m_pmem_info[i].pmem_fd = pmem_fd;
4998#ifdef USE_ION
4999 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5000 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5001 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5002#endif
5003
5004 /*Create a mapping between buffers*/
5005 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5006 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5007 &drv_ctx.ptr_outputbuffer[i];
5008 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5009 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5010 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05305011 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
5012 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
5013 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
Arun Menon906de572013-06-18 17:01:40 -07005014
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005015 DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
Arun Menon906de572013-06-18 17:01:40 -07005016 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5017 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5018 // Move the buffer and buffer header pointers
5019 bufHdr++;
5020 pPMEMInfo++;
5021 pPlatformEntry++;
5022 pPlatformList++;
5023 }
5024 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005025 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07005026 m_out_mem_ptr, pPtr);
5027 if (m_out_mem_ptr) {
5028 free(m_out_mem_ptr);
5029 m_out_mem_ptr = NULL;
5030 }
5031 if (pPtr) {
5032 free(pPtr);
5033 pPtr = NULL;
5034 }
5035 if (drv_ctx.ptr_outputbuffer) {
5036 free(drv_ctx.ptr_outputbuffer);
5037 drv_ctx.ptr_outputbuffer = NULL;
5038 }
5039 if (drv_ctx.ptr_respbuffer) {
5040 free(drv_ctx.ptr_respbuffer);
5041 drv_ctx.ptr_respbuffer = NULL;
5042 }
5043#ifdef USE_ION
5044 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005045 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07005046 free(drv_ctx.op_buf_ion_info);
5047 drv_ctx.op_buf_ion_info = NULL;
5048 }
5049#endif
5050 eRet = OMX_ErrorInsufficientResources;
5051 }
5052 if (eRet == OMX_ErrorNone)
5053 eRet = allocate_extradata();
5054 }
5055
5056 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
5057 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005058 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
Arun Menon906de572013-06-18 17:01:40 -07005059 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005060 }
5061 }
Arun Menon906de572013-06-18 17:01:40 -07005062
5063 if (eRet == OMX_ErrorNone) {
5064 if (i < drv_ctx.op_buf.actualcount) {
5065 struct v4l2_buffer buf;
5066 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5067 int rc;
5068 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5069
5070 drv_ctx.ptr_outputbuffer[i].buffer_len =
5071 drv_ctx.op_buf.buffer_size;
5072
5073 *bufferHdr = (m_out_mem_ptr + i );
5074 if (secure_mode) {
5075 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5076 }
5077 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5078
5079 buf.index = i;
5080 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5081 buf.memory = V4L2_MEMORY_USERPTR;
5082 plane[0].length = drv_ctx.op_buf.buffer_size;
5083 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5084 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005085#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005086 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005087#endif
Arun Menon906de572013-06-18 17:01:40 -07005088 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5089 plane[0].data_offset = 0;
5090 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5091 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5092 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5093 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 -07005094#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005095 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005096#endif
Arun Menon906de572013-06-18 17:01:40 -07005097 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5098 plane[extra_idx].data_offset = 0;
5099 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005100 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005101 return OMX_ErrorBadParameter;
5102 }
5103 buf.m.planes = plane;
5104 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005105 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 -07005106 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5107 if (rc) {
5108 /*TODO: How to handle this case */
5109 return OMX_ErrorInsufficientResources;
5110 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005111
Arun Menon906de572013-06-18 17:01:40 -07005112 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5113 enum v4l2_buf_type buf_type;
5114 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5115 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5116 if (rc) {
5117 return OMX_ErrorInsufficientResources;
5118 } else {
5119 streaming[CAPTURE_PORT] = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005120 DEBUG_PRINT_LOW("STREAMON Successful");
Arun Menon906de572013-06-18 17:01:40 -07005121 }
5122 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005123
Arun Menon906de572013-06-18 17:01:40 -07005124 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5125 (*bufferHdr)->pAppPrivate = appData;
5126 BITMASK_SET(&m_out_bm_count,i);
5127 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005128 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
Arun Menon906de572013-06-18 17:01:40 -07005129 eRet = OMX_ErrorInsufficientResources;
5130 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005131 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005132
Arun Menon906de572013-06-18 17:01:40 -07005133 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005134}
5135
5136
5137// AllocateBuffer -- API Call
5138/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005139 FUNCTION
5140 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005141
Arun Menon906de572013-06-18 17:01:40 -07005142 DESCRIPTION
5143 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005144
Arun Menon906de572013-06-18 17:01:40 -07005145 PARAMETERS
5146 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005147
Arun Menon906de572013-06-18 17:01:40 -07005148 RETURN VALUE
5149 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005150
Arun Menon906de572013-06-18 17:01:40 -07005151 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005152OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005153 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5154 OMX_IN OMX_U32 port,
5155 OMX_IN OMX_PTR appData,
5156 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005157{
5158 unsigned i = 0;
5159 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5160
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005161 DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005162 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005163 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005164 return OMX_ErrorInvalidState;
5165 }
5166
Arun Menon906de572013-06-18 17:01:40 -07005167 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5168 if (arbitrary_bytes) {
5169 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5170 } else {
5171 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5172 }
5173 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005174 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5175 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005176 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005177 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
Arun Menon906de572013-06-18 17:01:40 -07005178 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005179 }
5180 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005181 if (eRet == OMX_ErrorNone) {
5182 if (allocate_done()) {
5183 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005184 // Send the callback now
5185 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5186 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005187 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005188 }
5189 }
Arun Menon906de572013-06-18 17:01:40 -07005190 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5191 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5192 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5193 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005194 OMX_CORE_INPUT_PORT_INDEX,
5195 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005196 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005197 }
Arun Menon906de572013-06-18 17:01:40 -07005198 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5199 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5200 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005201 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005202 OMX_CORE_OUTPUT_PORT_INDEX,
5203 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005204 }
5205 }
5206 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005207 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005208 return eRet;
5209}
5210
5211// Free Buffer - API call
5212/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005213 FUNCTION
5214 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005215
Arun Menon906de572013-06-18 17:01:40 -07005216 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005217
Arun Menon906de572013-06-18 17:01:40 -07005218 PARAMETERS
5219 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005220
Arun Menon906de572013-06-18 17:01:40 -07005221 RETURN VALUE
5222 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005223
Arun Menon906de572013-06-18 17:01:40 -07005224 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005225OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005226 OMX_IN OMX_U32 port,
5227 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005228{
5229 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5230 unsigned int nPortIndex;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005231 DEBUG_PRINT_LOW("In for decoder free_buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005232
Arun Menon906de572013-06-18 17:01:40 -07005233 if (m_state == OMX_StateIdle &&
5234 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005235 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
Arun Menon906de572013-06-18 17:01:40 -07005236 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5237 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005238 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled", port);
Arun Menon906de572013-06-18 17:01:40 -07005239 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5240 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5241 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5242 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005243 DEBUG_PRINT_LOW("Free Buffer while port %lu enable pending", port);
Arun Menon906de572013-06-18 17:01:40 -07005244 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005245 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005246 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005247 OMX_ErrorPortUnpopulated,
5248 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005249
5250 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005251 } else if (m_state != OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005252 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005253 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005254 OMX_ErrorPortUnpopulated,
5255 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005256 }
5257
Arun Menon906de572013-06-18 17:01:40 -07005258 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5259 /*Check if arbitrary bytes*/
5260 if (!arbitrary_bytes && !input_use_buffer)
5261 nPortIndex = buffer - m_inp_mem_ptr;
5262 else
5263 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005264
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005265 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005266 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5267 // Clear the bit associated with it.
5268 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5269 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5270 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005271
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005272 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005273 if (m_phdr_pmem_ptr)
5274 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5275 } else {
5276 if (arbitrary_bytes) {
5277 if (m_phdr_pmem_ptr)
5278 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5279 else
5280 free_input_buffer(nPortIndex,NULL);
5281 } else
5282 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005283 }
Arun Menon906de572013-06-18 17:01:40 -07005284 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305285 if(release_input_done())
5286 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005287 /*Free the Buffer Header*/
5288 if (release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005289 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07005290 free_input_buffer_header();
5291 }
5292 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005293 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005294 eRet = OMX_ErrorBadPortIndex;
5295 }
5296
Arun Menon906de572013-06-18 17:01:40 -07005297 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5298 && release_input_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005299 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005300 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5301 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005302 OMX_CORE_INPUT_PORT_INDEX,
5303 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005304 }
Arun Menon906de572013-06-18 17:01:40 -07005305 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005306 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005307 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005308 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005309 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005310 // Clear the bit associated with it.
5311 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5312 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005313 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005314
Surajit Podder12aefac2013-08-06 18:43:32 +05305315 if(release_output_done()) {
5316 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5317 }
Arun Menon906de572013-06-18 17:01:40 -07005318 if (release_output_done()) {
5319 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005320 }
Arun Menon906de572013-06-18 17:01:40 -07005321 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005322 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005323 eRet = OMX_ErrorBadPortIndex;
5324 }
Arun Menon906de572013-06-18 17:01:40 -07005325 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5326 && release_output_done()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005327 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005328
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005329 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
Arun Menon906de572013-06-18 17:01:40 -07005330 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005331#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005332 if (m_enable_android_native_buffers) {
5333 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5334 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5335 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005336#endif
5337
Arun Menon906de572013-06-18 17:01:40 -07005338 post_event(OMX_CommandPortDisable,
5339 OMX_CORE_OUTPUT_PORT_INDEX,
5340 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005341 }
Arun Menon906de572013-06-18 17:01:40 -07005342 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005343 eRet = OMX_ErrorBadPortIndex;
5344 }
Arun Menon906de572013-06-18 17:01:40 -07005345 if ((eRet == OMX_ErrorNone) &&
5346 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5347 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005348 // Send the callback now
5349 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5350 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005351 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005352 }
5353 }
5354 return eRet;
5355}
5356
5357
5358/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005359 FUNCTION
5360 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005361
Arun Menon906de572013-06-18 17:01:40 -07005362 DESCRIPTION
5363 This routine is used to push the encoded video frames to
5364 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005365
Arun Menon906de572013-06-18 17:01:40 -07005366 PARAMETERS
5367 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005368
Arun Menon906de572013-06-18 17:01:40 -07005369 RETURN VALUE
5370 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005371
Arun Menon906de572013-06-18 17:01:40 -07005372 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005373OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005374 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005375{
Arun Menon906de572013-06-18 17:01:40 -07005376 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5377 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005378
Arun Menon906de572013-06-18 17:01:40 -07005379 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005380 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005381 return OMX_ErrorInvalidState;
5382 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005383
Arun Menon906de572013-06-18 17:01:40 -07005384 if (buffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005385 DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
Arun Menon906de572013-06-18 17:01:40 -07005386 return OMX_ErrorBadParameter;
5387 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005388
Arun Menon906de572013-06-18 17:01:40 -07005389 if (!m_inp_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005390 DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005391 return OMX_ErrorIncorrectStateOperation;
5392 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005393
Arun Menon906de572013-06-18 17:01:40 -07005394 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005395 DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005396 return OMX_ErrorBadPortIndex;
5397 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005398
5399#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005400 if (iDivXDrmDecrypt) {
5401 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5402 if (drmErr != OMX_ErrorNone) {
5403 // this error can be ignored
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005404 DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
Arun Menon906de572013-06-18 17:01:40 -07005405 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005406 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005407#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005408 if (perf_flag) {
5409 if (!latency) {
5410 dec_time.stop();
5411 latency = dec_time.processing_time_us();
5412 dec_time.start();
5413 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005414 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005415
Arun Menon906de572013-06-18 17:01:40 -07005416 if (arbitrary_bytes) {
5417 nBufferIndex = buffer - m_inp_heap_ptr;
5418 } else {
5419 if (input_use_buffer == true) {
5420 nBufferIndex = buffer - m_inp_heap_ptr;
5421 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5422 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5423 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5424 buffer = &m_inp_mem_ptr[nBufferIndex];
5425 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5426 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5427 } else {
5428 nBufferIndex = buffer - m_inp_mem_ptr;
5429 }
5430 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005431
Arun Menon906de572013-06-18 17:01:40 -07005432 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005433 DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005434 return OMX_ErrorBadParameter;
5435 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005436
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005437 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5438 codec_config_flag = true;
5439 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5440 }
5441
Arun Menon906de572013-06-18 17:01:40 -07005442 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5443 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5444 if (arbitrary_bytes) {
5445 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005446 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005447 } else {
5448 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5449 set_frame_rate(buffer->nTimeStamp);
5450 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5451 }
5452 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005453}
5454
5455/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005456 FUNCTION
5457 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005458
Arun Menon906de572013-06-18 17:01:40 -07005459 DESCRIPTION
5460 This routine is used to push the encoded video frames to
5461 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005462
Arun Menon906de572013-06-18 17:01:40 -07005463 PARAMETERS
5464 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005465
Arun Menon906de572013-06-18 17:01:40 -07005466 RETURN VALUE
5467 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005468
Arun Menon906de572013-06-18 17:01:40 -07005469 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005470OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005471 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005472{
Arun Menon906de572013-06-18 17:01:40 -07005473 int push_cnt = 0,i=0;
5474 unsigned nPortIndex = 0;
5475 OMX_ERRORTYPE ret = OMX_ErrorNone;
5476 struct vdec_input_frameinfo frameinfo;
5477 struct vdec_bufferpayload *temp_buffer;
5478 struct vdec_seqheader seq_header;
5479 bool port_setting_changed = true;
5480 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005481
Arun Menon906de572013-06-18 17:01:40 -07005482 /*Should we generate a Aync error event*/
5483 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005484 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
Arun Menon906de572013-06-18 17:01:40 -07005485 return OMX_ErrorBadParameter;
5486 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005487
Arun Menon906de572013-06-18 17:01:40 -07005488 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005489
Arun Menon906de572013-06-18 17:01:40 -07005490 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005491 DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
Arun Menon906de572013-06-18 17:01:40 -07005492 nPortIndex);
5493 return OMX_ErrorBadParameter;
5494 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005495
Arun Menon906de572013-06-18 17:01:40 -07005496 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005497
Arun Menon906de572013-06-18 17:01:40 -07005498 /* return zero length and not an EOS buffer */
5499 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5500 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005501 DEBUG_PRINT_HIGH("return zero legth buffer");
Arun Menon906de572013-06-18 17:01:40 -07005502 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5503 OMX_COMPONENT_GENERATE_EBD);
5504 return OMX_ErrorNone;
5505 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005506
5507
Arun Menon906de572013-06-18 17:01:40 -07005508 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5509 mp4StreamType psBits;
5510 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5511 psBits.numBytes = buffer->nFilledLen;
5512 mp4_headerparser.parseHeader(&psBits);
5513 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5514 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5515 if (not_coded_vop) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005516 DEBUG_PRINT_HIGH("Found Not coded vop len %lu frame number %u",
Arun Menon906de572013-06-18 17:01:40 -07005517 buffer->nFilledLen,frame_count);
5518 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005519 DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
Arun Menon906de572013-06-18 17:01:40 -07005520 not_coded_vop = false;
5521 buffer->nFilledLen = 0;
5522 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005523 }
5524 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005525
Arun Menon906de572013-06-18 17:01:40 -07005526 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005527
Arun Menon906de572013-06-18 17:01:40 -07005528 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005529
Arun Menon906de572013-06-18 17:01:40 -07005530 ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005531 DEBUG_PRINT_LOW("Flush in progress return buffer ");
Arun Menon906de572013-06-18 17:01:40 -07005532 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5533 OMX_COMPONENT_GENERATE_EBD);
5534 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005535 }
5536
Arun Menon906de572013-06-18 17:01:40 -07005537 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005538
Surajit Podderd2644d52013-08-28 17:59:06 +05305539 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
Arun Menon906de572013-06-18 17:01:40 -07005540 return OMX_ErrorBadParameter;
5541 }
5542 /* If its first frame, H264 codec and reject is true, then parse the nal
5543 and get the profile. Based on this, reject the clip playback */
5544 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5545 m_reject_avc_1080p_mp) {
5546 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005547 DEBUG_PRINT_ERROR("Parse nal to get the profile");
Arun Menon906de572013-06-18 17:01:40 -07005548 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5549 NALU_TYPE_SPS);
5550 m_profile = h264_parser->get_profile();
5551 ret = is_video_session_supported();
5552 if (ret) {
5553 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5554 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5555 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5556 m_state = OMX_StateInvalid;
5557 return OMX_ErrorNone;
5558 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005559 }
5560
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005561 DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Arun Menon906de572013-06-18 17:01:40 -07005562 /*for use buffer we need to memcpy the data*/
5563 temp_buffer->buffer_len = buffer->nFilledLen;
5564
5565 if (input_use_buffer) {
5566 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5567 if (arbitrary_bytes) {
5568 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5569 } else {
5570 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5571 buffer->nFilledLen);
5572 }
5573 } else {
5574 return OMX_ErrorBadParameter;
5575 }
5576
5577 }
5578
5579 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5580 frameinfo.client_data = (void *) buffer;
5581 frameinfo.datalen = temp_buffer->buffer_len;
5582 frameinfo.flags = 0;
5583 frameinfo.offset = buffer->nOffset;
5584 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5585 frameinfo.pmem_offset = temp_buffer->offset;
5586 frameinfo.timestamp = buffer->nTimeStamp;
5587 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5588 DEBUG_PRINT_LOW("ETB: dmx enabled");
5589 if (m_demux_entries == 0) {
5590 extract_demux_addr_offsets(buffer);
5591 }
5592
5593 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5594 handle_demux_data(buffer);
5595 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5596 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5597 } else {
5598 frameinfo.desc_addr = NULL;
5599 frameinfo.desc_size = 0;
5600 }
5601 if (!arbitrary_bytes) {
5602 frameinfo.flags |= buffer->nFlags;
5603 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005604
5605#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005606 if (m_debug_timestamp) {
5607 if (arbitrary_bytes) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005608 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005609 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5610 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005611 DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07005612 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5613 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005614 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005615#endif
5616
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005617log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005618
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005619if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005620 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5621 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5622 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005623
Arun Menon906de572013-06-18 17:01:40 -07005624 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005625 DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07005626 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5627 h264_scratch.nFilledLen = 0;
5628 nal_count = 0;
5629 look_ahead_nal = false;
5630 frame_count = 0;
5631 if (m_frame_parser.mutils)
5632 m_frame_parser.mutils->initialize_frame_checking_environment();
5633 m_frame_parser.flush();
5634 h264_last_au_ts = LLONG_MAX;
5635 h264_last_au_flags = 0;
5636 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5637 m_demux_entries = 0;
5638 }
5639 struct v4l2_buffer buf;
5640 struct v4l2_plane plane;
5641 memset( (void *)&buf, 0, sizeof(buf));
5642 memset( (void *)&plane, 0, sizeof(plane));
5643 int rc;
5644 unsigned long print_count;
5645 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005646 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005647 DEBUG_PRINT_HIGH("INPUT EOS reached") ;
Arun Menon906de572013-06-18 17:01:40 -07005648 }
5649 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5650 buf.index = nPortIndex;
5651 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5652 buf.memory = V4L2_MEMORY_USERPTR;
5653 plane.bytesused = temp_buffer->buffer_len;
5654 plane.length = drv_ctx.ip_buf.buffer_size;
5655 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5656 (unsigned long)temp_buffer->offset;
5657 plane.reserved[0] = temp_buffer->pmem_fd;
5658 plane.reserved[1] = temp_buffer->offset;
5659 plane.data_offset = 0;
5660 buf.m.planes = &plane;
5661 buf.length = 1;
5662 if (frameinfo.timestamp >= LLONG_MAX) {
5663 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5664 }
5665 //assumption is that timestamp is in milliseconds
5666 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5667 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5668 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5669 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005670
Arun Menon906de572013-06-18 17:01:40 -07005671 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5672 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005673 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
Arun Menon906de572013-06-18 17:01:40 -07005674 return OMX_ErrorHardware;
5675 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07005676 if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5677 codec_config_flag = false;
5678 }
Arun Menon906de572013-06-18 17:01:40 -07005679 if (!streaming[OUTPUT_PORT]) {
5680 enum v4l2_buf_type buf_type;
5681 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005682
Arun Menon906de572013-06-18 17:01:40 -07005683 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005684 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
Arun Menon906de572013-06-18 17:01:40 -07005685 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5686 if (!ret) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005687 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
Arun Menon906de572013-06-18 17:01:40 -07005688 streaming[OUTPUT_PORT] = true;
5689 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005690 DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
Arun Menon906de572013-06-18 17:01:40 -07005691 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5692 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5693 OMX_COMPONENT_GENERATE_EBD);
5694 return OMX_ErrorBadParameter;
5695 }
5696 }
5697 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5698 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5699 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005700
Arun Menon906de572013-06-18 17:01:40 -07005701 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005702}
5703
5704/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005705 FUNCTION
5706 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005707
Arun Menon906de572013-06-18 17:01:40 -07005708 DESCRIPTION
5709 IL client uses this method to release the frame buffer
5710 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005711
Arun Menon906de572013-06-18 17:01:40 -07005712 PARAMETERS
5713 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005714
Arun Menon906de572013-06-18 17:01:40 -07005715 RETURN VALUE
5716 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005717
Arun Menon906de572013-06-18 17:01:40 -07005718 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005719OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005720 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005721{
Arun Menonbdb80b02013-08-12 17:45:54 -07005722 if (dynamic_buf_mode) {
5723 private_handle_t *handle = NULL;
5724 struct VideoDecoderOutputMetaData *meta;
5725 OMX_U8 *buff = NULL;
5726 unsigned int nPortIndex = 0;
5727
5728 if (!buffer || !buffer->pBuffer) {
5729 DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
5730 return OMX_ErrorBadParameter;
5731 }
5732
5733 //get the buffer type and fd info
5734 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5735 handle = (private_handle_t *)meta->pHandle;
5736 DEBUG_PRINT_LOW("FTB: buftype: %d bufhndl: %p", meta->eType, meta->pHandle);
5737
5738 //map the buffer handle based on the size set on output port definition.
5739 if (!secure_mode) {
5740 buff = (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5741 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
5742 } else {
5743 buff = (OMX_U8*) buffer;
5744 }
5745
5746 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5747 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5748 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
5749 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5750 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = buff;
5751 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5752 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5753 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5754 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5755 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005756
Arun Menon906de572013-06-18 17:01:40 -07005757 if (m_state == OMX_StateInvalid) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005758 DEBUG_PRINT_ERROR("FTB in Invalid State");
Arun Menon906de572013-06-18 17:01:40 -07005759 return OMX_ErrorInvalidState;
5760 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005761
Arun Menon906de572013-06-18 17:01:40 -07005762 if (!m_out_bEnabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005763 DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
Arun Menon906de572013-06-18 17:01:40 -07005764 return OMX_ErrorIncorrectStateOperation;
5765 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005766
Arun Menon906de572013-06-18 17:01:40 -07005767 if (buffer == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05305768 ((buffer - client_buffers.get_il_buf_hdr()) >= (int)drv_ctx.op_buf.actualcount)) {
Arun Menon906de572013-06-18 17:01:40 -07005769 return OMX_ErrorBadParameter;
5770 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005771
Arun Menon906de572013-06-18 17:01:40 -07005772 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005773 DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005774 return OMX_ErrorBadPortIndex;
5775 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005776
Arun Menon906de572013-06-18 17:01:40 -07005777 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5778 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5779 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005780}
5781/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005782 FUNCTION
5783 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005784
Arun Menon906de572013-06-18 17:01:40 -07005785 DESCRIPTION
5786 IL client uses this method to release the frame buffer
5787 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005788
Arun Menon906de572013-06-18 17:01:40 -07005789 PARAMETERS
5790 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005791
Arun Menon906de572013-06-18 17:01:40 -07005792 RETURN VALUE
5793 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005794
Arun Menon906de572013-06-18 17:01:40 -07005795 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005796OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005797 OMX_IN OMX_HANDLETYPE hComp,
5798 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005799{
Arun Menon906de572013-06-18 17:01:40 -07005800 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5801 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5802 unsigned nPortIndex = 0;
5803 struct vdec_fillbuffer_cmd fillbuffer;
5804 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5805 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005806
Arun Menon906de572013-06-18 17:01:40 -07005807 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005808
Arun Menon906de572013-06-18 17:01:40 -07005809 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5810 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005811
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005812 DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07005813 bufferAdd, bufferAdd->pBuffer);
5814 /*Return back the output buffer to client*/
5815 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005816 DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
Arun Menon906de572013-06-18 17:01:40 -07005817 buffer->nFilledLen = 0;
5818 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5819 return OMX_ErrorNone;
5820 }
5821 pending_output_buffers++;
5822 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5823 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5824 if (ptr_respbuffer) {
5825 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5826 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005827
Arun Menon906de572013-06-18 17:01:40 -07005828 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5829 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5830 buffer->nFilledLen = 0;
5831 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5832 pending_output_buffers--;
5833 return OMX_ErrorBadParameter;
5834 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005835
Arun Menon906de572013-06-18 17:01:40 -07005836 int rc = 0;
5837 struct v4l2_buffer buf;
5838 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5839 memset( (void *)&buf, 0, sizeof(buf));
5840 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5841 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005842
Arun Menon906de572013-06-18 17:01:40 -07005843 buf.index = nPortIndex;
5844 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5845 buf.memory = V4L2_MEMORY_USERPTR;
5846 plane[0].bytesused = buffer->nFilledLen;
5847 plane[0].length = drv_ctx.op_buf.buffer_size;
5848 plane[0].m.userptr =
5849 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5850 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5851 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5852 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5853 plane[0].data_offset = 0;
5854 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5855 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5856 plane[extra_idx].bytesused = 0;
5857 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5858 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 -07005859#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005860 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005861#endif
Arun Menon906de572013-06-18 17:01:40 -07005862 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5863 plane[extra_idx].data_offset = 0;
5864 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005865 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07005866 return OMX_ErrorBadParameter;
5867 }
5868 buf.m.planes = plane;
5869 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005870 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07005871 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5872
Arun Menon906de572013-06-18 17:01:40 -07005873 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5874 if (rc) {
5875 /*TODO: How to handle this case */
5876 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5877 }
Arun Menon906de572013-06-18 17:01:40 -07005878return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005879}
5880
5881/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005882 FUNCTION
5883 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005884
Arun Menon906de572013-06-18 17:01:40 -07005885 DESCRIPTION
5886 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005887
Arun Menon906de572013-06-18 17:01:40 -07005888 PARAMETERS
5889 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005890
Arun Menon906de572013-06-18 17:01:40 -07005891 RETURN VALUE
5892 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005893
Arun Menon906de572013-06-18 17:01:40 -07005894 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005895OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005896 OMX_IN OMX_CALLBACKTYPE* callbacks,
5897 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005898{
5899
Arun Menon906de572013-06-18 17:01:40 -07005900 m_cb = *callbacks;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005901 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
Arun Menon906de572013-06-18 17:01:40 -07005902 m_cb.EventHandler,m_cb.FillBufferDone);
5903 m_app_data = appData;
5904 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005905}
5906
5907/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005908 FUNCTION
5909 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005910
Arun Menon906de572013-06-18 17:01:40 -07005911 DESCRIPTION
5912 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005913
Arun Menon906de572013-06-18 17:01:40 -07005914 PARAMETERS
5915 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005916
Arun Menon906de572013-06-18 17:01:40 -07005917 RETURN VALUE
5918 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005919
Arun Menon906de572013-06-18 17:01:40 -07005920 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005921OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5922{
5923#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005924 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005925 delete iDivXDrmDecrypt;
5926 iDivXDrmDecrypt=NULL;
5927 }
5928#endif //_ANDROID_
5929
Shalaj Jain286b0062013-02-21 20:35:48 -08005930 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005931 if (OMX_StateLoaded != m_state) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005932 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
Arun Menon906de572013-06-18 17:01:40 -07005933 m_state);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005934 DEBUG_PRINT_ERROR("Playback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005935 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005936 DEBUG_PRINT_HIGH("Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005937 }
5938
5939 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005940 if (m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005941 DEBUG_PRINT_LOW("Freeing the Output Memory");
Arun Menon906de572013-06-18 17:01:40 -07005942 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5943 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005944 }
5945#ifdef _ANDROID_ICS_
5946 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5947#endif
5948 }
5949
5950 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005951 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005952 DEBUG_PRINT_LOW("Freeing the Input Memory");
Arun Menon906de572013-06-18 17:01:40 -07005953 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5954 if (m_inp_mem_ptr)
5955 free_input_buffer (i,&m_inp_mem_ptr[i]);
5956 else
5957 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005958 }
5959 }
5960 free_input_buffer_header();
5961 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005962 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005963 free(h264_scratch.pBuffer);
5964 h264_scratch.pBuffer = NULL;
5965 }
5966
Arun Menon906de572013-06-18 17:01:40 -07005967 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005968 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005969 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005970 }
5971
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07005972 if (m_frame_parser.mutils) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07005973 DEBUG_PRINT_LOW("Free utils parser");
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07005974 delete (m_frame_parser.mutils);
5975 m_frame_parser.mutils = NULL;
5976 }
5977
Arun Menon906de572013-06-18 17:01:40 -07005978 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005979 free(m_platform_list);
5980 m_platform_list = NULL;
5981 }
Arun Menon906de572013-06-18 17:01:40 -07005982 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005983 free(m_vendor_config.pData);
5984 m_vendor_config.pData = NULL;
5985 }
5986
5987 // Reset counters in mesg queues
5988 m_ftb_q.m_size=0;
5989 m_cmd_q.m_size=0;
5990 m_etb_q.m_size=0;
5991 m_ftb_q.m_read = m_ftb_q.m_write =0;
5992 m_cmd_q.m_read = m_cmd_q.m_write =0;
5993 m_etb_q.m_read = m_etb_q.m_write =0;
5994#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005995 if (m_debug_timestamp) {
5996 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005997 }
5998#endif
5999
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006000 DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006001 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07006002 // NULL);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006003 DEBUG_PRINT_HIGH("Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07006004
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006005 if (m_debug.infile) {
6006 fclose(m_debug.infile);
6007 m_debug.infile = NULL;
6008 }
6009 if (m_debug.outfile) {
6010 fclose(m_debug.outfile);
6011 m_debug.outfile = NULL;
6012 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006013#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07006014 if (outputExtradataFile)
6015 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006016#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006017 DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
Arun Menon906de572013-06-18 17:01:40 -07006018 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006019}
6020
6021/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006022 FUNCTION
6023 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07006024
Arun Menon906de572013-06-18 17:01:40 -07006025 DESCRIPTION
6026 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006027
Arun Menon906de572013-06-18 17:01:40 -07006028 PARAMETERS
6029 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006030
Arun Menon906de572013-06-18 17:01:40 -07006031 RETURN VALUE
6032 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006033
Arun Menon906de572013-06-18 17:01:40 -07006034 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006035OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006036 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6037 OMX_IN OMX_U32 port,
6038 OMX_IN OMX_PTR appData,
6039 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006040{
Arun Menon906de572013-06-18 17:01:40 -07006041 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6042 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6043 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006044
6045#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006046 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6047 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006048#else
Arun Menon906de572013-06-18 17:01:40 -07006049 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006050#endif
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006051 DEBUG_PRINT_HIGH("use EGL image support for decoder");
Arun Menon906de572013-06-18 17:01:40 -07006052 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006053 DEBUG_PRINT_ERROR("");
Arun Menon906de572013-06-18 17:01:40 -07006054 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006055#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07006056 if (m_display_id == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006057 DEBUG_PRINT_ERROR("Display ID is not set by IL client");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006058 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006059 }
6060 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6061 eglGetProcAddress("eglQueryImageKHR");
6062 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6063 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6064 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006065#else //with OMX test app
6066 struct temp_egl {
6067 int pmem_fd;
6068 int offset;
6069 };
6070 struct temp_egl *temp_egl_id = NULL;
6071 void * pmemPtr = (void *) eglImage;
6072 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07006073 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006074 fd = temp_egl_id->pmem_fd;
6075 offset = temp_egl_id->offset;
6076 }
6077#endif
6078 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006079 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006080 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07006081 }
6082 pmem_info.pmem_fd = (OMX_U32) fd;
6083 pmem_info.offset = (OMX_U32) offset;
6084 pmem_entry.entry = (void *) &pmem_info;
6085 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6086 pmem_list.entryList = &pmem_entry;
6087 pmem_list.nEntries = 1;
6088 ouput_egl_buffers = true;
6089 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6090 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6091 (OMX_U8 *)pmemPtr)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006092 DEBUG_PRINT_ERROR("use buffer call failed for egl image");
Arun Menon906de572013-06-18 17:01:40 -07006093 return OMX_ErrorInsufficientResources;
6094 }
6095 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006096}
6097
6098/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006099 FUNCTION
6100 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006101
Arun Menon906de572013-06-18 17:01:40 -07006102 DESCRIPTION
6103 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006104
Arun Menon906de572013-06-18 17:01:40 -07006105 PARAMETERS
6106 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006107
Arun Menon906de572013-06-18 17:01:40 -07006108 RETURN VALUE
6109 OMX Error None if everything is successful.
6110 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006111OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006112 OMX_OUT OMX_U8* role,
6113 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006114{
Arun Menon906de572013-06-18 17:01:40 -07006115 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006116
Arun Menon906de572013-06-18 17:01:40 -07006117 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6118 if ((0 == index) && role) {
6119 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006120 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006121 } else {
6122 eRet = OMX_ErrorNoMore;
6123 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006124 }
Arun Menon906de572013-06-18 17:01:40 -07006125 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6126 if ((0 == index) && role) {
6127 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006128 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006129 } else {
6130 eRet = OMX_ErrorNoMore;
6131 }
6132 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6133 if ((0 == index) && role) {
6134 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006135 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006136 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006137 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006138 eRet = OMX_ErrorNoMore;
6139 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006140 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006141
Arun Menon906de572013-06-18 17:01:40 -07006142 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6143 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6144 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006145
Shalaj Jain273b3e02012-06-22 19:08:03 -07006146 {
Arun Menon906de572013-06-18 17:01:40 -07006147 if ((0 == index) && role) {
6148 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006149 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006150 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006151 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006152 eRet = OMX_ErrorNoMore;
6153 }
6154 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6155 if ((0 == index) && role) {
6156 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006157 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006158 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006159 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006160 eRet = OMX_ErrorNoMore;
6161 }
6162 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6163 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6164 ) {
6165 if ((0 == index) && role) {
6166 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006167 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006168 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006169 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006170 eRet = OMX_ErrorNoMore;
6171 }
6172 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6173 if ((0 == index) && role) {
6174 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006175 DEBUG_PRINT_LOW("component_role_enum: role %s",role);
Arun Menon906de572013-06-18 17:01:40 -07006176 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006177 DEBUG_PRINT_LOW("No more roles");
Arun Menon906de572013-06-18 17:01:40 -07006178 eRet = OMX_ErrorNoMore;
6179 }
6180 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006181 DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
Arun Menon906de572013-06-18 17:01:40 -07006182 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006183 }
Arun Menon906de572013-06-18 17:01:40 -07006184 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006185}
6186
6187
6188
6189
6190/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006191 FUNCTION
6192 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006193
Arun Menon906de572013-06-18 17:01:40 -07006194 DESCRIPTION
6195 Checks if entire buffer pool is allocated by IL Client or not.
6196 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006197
Arun Menon906de572013-06-18 17:01:40 -07006198 PARAMETERS
6199 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006200
Arun Menon906de572013-06-18 17:01:40 -07006201 RETURN VALUE
6202 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006203
Arun Menon906de572013-06-18 17:01:40 -07006204 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006205bool omx_vdec::allocate_done(void)
6206{
Arun Menon906de572013-06-18 17:01:40 -07006207 bool bRet = false;
6208 bool bRet_In = false;
6209 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006210
Arun Menon906de572013-06-18 17:01:40 -07006211 bRet_In = allocate_input_done();
6212 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006213
Arun Menon906de572013-06-18 17:01:40 -07006214 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006215 bRet = true;
6216 }
Arun Menon906de572013-06-18 17:01:40 -07006217
6218 return bRet;
6219}
6220/* ======================================================================
6221 FUNCTION
6222 omx_vdec::AllocateInputDone
6223
6224 DESCRIPTION
6225 Checks if I/P buffer pool is allocated by IL Client or not.
6226
6227 PARAMETERS
6228 None.
6229
6230 RETURN VALUE
6231 true/false.
6232
6233 ========================================================================== */
6234bool omx_vdec::allocate_input_done(void)
6235{
6236 bool bRet = false;
6237 unsigned i=0;
6238
6239 if (m_inp_mem_ptr == NULL) {
6240 return bRet;
6241 }
6242 if (m_inp_mem_ptr ) {
6243 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6244 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6245 break;
6246 }
6247 }
6248 }
6249 if (i == drv_ctx.ip_buf.actualcount) {
6250 bRet = true;
6251 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6252 }
6253 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6254 m_inp_bPopulated = OMX_TRUE;
6255 }
6256 return bRet;
6257}
6258/* ======================================================================
6259 FUNCTION
6260 omx_vdec::AllocateOutputDone
6261
6262 DESCRIPTION
6263 Checks if entire O/P buffer pool is allocated by IL Client or not.
6264
6265 PARAMETERS
6266 None.
6267
6268 RETURN VALUE
6269 true/false.
6270
6271 ========================================================================== */
6272bool omx_vdec::allocate_output_done(void)
6273{
6274 bool bRet = false;
6275 unsigned j=0;
6276
6277 if (m_out_mem_ptr == NULL) {
6278 return bRet;
6279 }
6280
6281 if (m_out_mem_ptr) {
6282 for (; j < drv_ctx.op_buf.actualcount; j++) {
6283 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6284 break;
6285 }
6286 }
6287 }
6288
6289 if (j == drv_ctx.op_buf.actualcount) {
6290 bRet = true;
6291 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6292 if (m_out_bEnabled)
6293 m_out_bPopulated = OMX_TRUE;
6294 }
6295
6296 return bRet;
6297}
6298
6299/* ======================================================================
6300 FUNCTION
6301 omx_vdec::ReleaseDone
6302
6303 DESCRIPTION
6304 Checks if IL client has released all the buffers.
6305
6306 PARAMETERS
6307 None.
6308
6309 RETURN VALUE
6310 true/false
6311
6312 ========================================================================== */
6313bool omx_vdec::release_done(void)
6314{
6315 bool bRet = false;
6316
6317 if (release_input_done()) {
6318 if (release_output_done()) {
6319 bRet = true;
6320 }
6321 }
6322 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006323}
6324
6325
6326/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006327 FUNCTION
6328 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006329
Arun Menon906de572013-06-18 17:01:40 -07006330 DESCRIPTION
6331 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006332
Arun Menon906de572013-06-18 17:01:40 -07006333 PARAMETERS
6334 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006335
Arun Menon906de572013-06-18 17:01:40 -07006336 RETURN VALUE
6337 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006338
Arun Menon906de572013-06-18 17:01:40 -07006339 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006340bool omx_vdec::release_output_done(void)
6341{
Arun Menon906de572013-06-18 17:01:40 -07006342 bool bRet = false;
6343 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006344
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006345 DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006346 if (m_out_mem_ptr) {
6347 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6348 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6349 break;
6350 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006351 }
Arun Menon906de572013-06-18 17:01:40 -07006352 if (j == drv_ctx.op_buf.actualcount) {
6353 m_out_bm_count = 0;
6354 bRet = true;
6355 }
6356 } else {
6357 m_out_bm_count = 0;
6358 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006359 }
Arun Menon906de572013-06-18 17:01:40 -07006360 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006361}
6362/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006363 FUNCTION
6364 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006365
Arun Menon906de572013-06-18 17:01:40 -07006366 DESCRIPTION
6367 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006368
Arun Menon906de572013-06-18 17:01:40 -07006369 PARAMETERS
6370 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006371
Arun Menon906de572013-06-18 17:01:40 -07006372 RETURN VALUE
6373 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006374
Arun Menon906de572013-06-18 17:01:40 -07006375 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006376bool omx_vdec::release_input_done(void)
6377{
Arun Menon906de572013-06-18 17:01:40 -07006378 bool bRet = false;
6379 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006380
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006381 DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
Arun Menon906de572013-06-18 17:01:40 -07006382 if (m_inp_mem_ptr) {
6383 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6384 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6385 break;
6386 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006387 }
Arun Menon906de572013-06-18 17:01:40 -07006388 if (j==drv_ctx.ip_buf.actualcount) {
6389 bRet = true;
6390 }
6391 } else {
6392 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006393 }
Arun Menon906de572013-06-18 17:01:40 -07006394 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006395}
6396
6397OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006398 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006399{
Arun Menon906de572013-06-18 17:01:40 -07006400 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
Surajit Podderd2644d52013-08-28 17:59:06 +05306401 if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006402 DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006403 return OMX_ErrorBadParameter;
6404 } else if (output_flush_progress) {
6405 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6406 buffer->nFilledLen = 0;
6407 buffer->nTimeStamp = 0;
6408 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6409 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6410 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006411 }
6412
Arun Menon906de572013-06-18 17:01:40 -07006413 if (m_debug_extradata) {
6414 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006415 DEBUG_PRINT_HIGH("");
6416 DEBUG_PRINT_HIGH("***************************************************");
6417 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
6418 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006419 }
6420
6421 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006422 DEBUG_PRINT_HIGH("");
6423 DEBUG_PRINT_HIGH("***************************************************");
6424 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
6425 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07006426 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006427 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006428
6429
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006430 DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006431 buffer, buffer->pBuffer);
6432 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006433
Arun Menonbdb80b02013-08-12 17:45:54 -07006434 if (dynamic_buf_mode && !secure_mode) {
6435 unsigned int nPortIndex = 0;
6436 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6437 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6438 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6439 }
Arun Menon906de572013-06-18 17:01:40 -07006440 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006441 DEBUG_PRINT_HIGH("Output EOS has been reached");
Arun Menon906de572013-06-18 17:01:40 -07006442 if (!output_flush_progress)
6443 post_event((unsigned)NULL, (unsigned)NULL,
6444 OMX_COMPONENT_GENERATE_EOS_DONE);
6445
6446 if (psource_frame) {
6447 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6448 psource_frame = NULL;
6449 }
6450 if (pdest_frame) {
6451 pdest_frame->nFilledLen = 0;
6452 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6453 (unsigned)NULL);
6454 pdest_frame = NULL;
6455 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006456 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006457
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006458 DEBUG_PRINT_LOW("In fill Buffer done call address %p ",buffer);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006459 log_output_buffers(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006460
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006461 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6462 DEBUG_PRINT_LOW("Processing extradata");
6463 handle_extradata(buffer);
6464 }
6465
Arun Menon906de572013-06-18 17:01:40 -07006466 /* For use buffer we need to copy the data */
6467 if (!output_flush_progress) {
6468 /* This is the error check for non-recoverable errros */
6469 bool is_duplicate_ts_valid = true;
6470 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006471
Arun Menon906de572013-06-18 17:01:40 -07006472 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6473 output_capability == V4L2_PIX_FMT_MPEG2 ||
6474 output_capability == V4L2_PIX_FMT_DIVX ||
6475 output_capability == V4L2_PIX_FMT_DIVX_311)
6476 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006477
Arun Menon906de572013-06-18 17:01:40 -07006478 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6479 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6480 if (mbaff) {
6481 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306482 }
Arun Menon906de572013-06-18 17:01:40 -07006483 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306484
Arun Menon906de572013-06-18 17:01:40 -07006485 if (buffer->nFilledLen > 0) {
6486 time_stamp_dts.get_next_timestamp(buffer,
6487 is_interlaced && is_duplicate_ts_valid);
6488 if (m_debug_timestamp) {
6489 {
6490 OMX_TICKS expected_ts = 0;
6491 m_timestamp_list.pop_min_ts(expected_ts);
6492 if (is_interlaced && is_duplicate_ts_valid) {
6493 m_timestamp_list.pop_min_ts(expected_ts);
6494 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006495 DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
Arun Menon906de572013-06-18 17:01:40 -07006496 buffer->nTimeStamp, expected_ts);
6497
6498 if (buffer->nTimeStamp != expected_ts) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006499 DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
Arun Menon906de572013-06-18 17:01:40 -07006500 }
6501 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306502 }
Arun Menon906de572013-06-18 17:01:40 -07006503 } else {
6504 m_inp_err_count++;
6505 time_stamp_dts.remove_time_stamp(
6506 buffer->nTimeStamp,
6507 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306508 }
Arun Menon906de572013-06-18 17:01:40 -07006509
6510
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006511 }
Arun Menon906de572013-06-18 17:01:40 -07006512 if (m_cb.FillBufferDone) {
6513 if (buffer->nFilledLen > 0) {
Arun Menon906de572013-06-18 17:01:40 -07006514 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6515 set_frame_rate(buffer->nTimeStamp);
6516 else if (arbitrary_bytes)
6517 adjust_timestamp(buffer->nTimeStamp);
6518 if (perf_flag) {
6519 if (!proc_frms) {
6520 dec_time.stop();
6521 latency = dec_time.processing_time_us() - latency;
6522 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6523 dec_time.start();
6524 fps_metrics.start();
6525 }
6526 proc_frms++;
6527 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6528 OMX_U64 proc_time = 0;
6529 fps_metrics.stop();
6530 proc_time = fps_metrics.processing_time_us();
6531 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006532 proc_frms, (float)proc_time / 1e6,
6533 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006534 proc_frms = 0;
6535 }
6536 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006537
6538#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006539 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006540
Arun Menon906de572013-06-18 17:01:40 -07006541 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6542 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6543 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6544 buffer->nFilledLen + 3)&(~3));
6545 while (p_extra &&
6546 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006547 DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
Arun Menon906de572013-06-18 17:01:40 -07006548 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6549 if (p_extra->eType == OMX_ExtraDataNone) {
6550 break;
6551 }
6552 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6553 }
6554 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006555#endif
Arun Menon906de572013-06-18 17:01:40 -07006556 }
6557 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6558 prev_ts = LLONG_MAX;
6559 rst_prev_ts = true;
6560 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006561
Arun Menon906de572013-06-18 17:01:40 -07006562 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6563 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6564 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006565 DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006566 OMX_BUFFERHEADERTYPE *il_buffer;
6567 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6568 if (il_buffer)
6569 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6570 else {
6571 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6572 return OMX_ErrorBadParameter;
6573 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006574 DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006575 } else {
6576 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006577 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006578
Praveen Chavancf924182013-12-06 23:16:23 -08006579#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
6580 if (m_smoothstreaming_mode) {
6581 OMX_U32 buf_index = buffer - m_out_mem_ptr;
6582 BufferDim_t dim;
6583 dim.sliceWidth = drv_ctx.video_resolution.frame_width;
6584 dim.sliceHeight = drv_ctx.video_resolution.frame_height;
6585 private_handle_t *private_handle = native_buffer[buf_index].privatehandle;
6586 if (private_handle) {
6587 DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
6588 dim.sliceWidth, dim.sliceHeight);
6589 setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
6590 }
6591 }
6592#endif
6593
Arun Menon906de572013-06-18 17:01:40 -07006594 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006595}
6596
6597OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006598 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006599{
6600
Surajit Podderd2644d52013-08-28 17:59:06 +05306601 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006602 DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006603 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006604 }
6605
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006606 DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006607 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006608 pending_input_buffers--;
6609
Arun Menon906de572013-06-18 17:01:40 -07006610 if (arbitrary_bytes) {
6611 if (pdest_frame == NULL && input_flush_progress == false) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006612 DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006613 pdest_frame = buffer;
6614 buffer->nFilledLen = 0;
6615 buffer->nTimeStamp = LLONG_MAX;
6616 push_input_buffer (hComp);
6617 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006618 DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006619 buffer->nFilledLen = 0;
6620 if (!m_input_free_q.insert_entry((unsigned)buffer,
6621 (unsigned)NULL, (unsigned)NULL)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006622 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
Arun Menon906de572013-06-18 17:01:40 -07006623 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006624 }
Arun Menon906de572013-06-18 17:01:40 -07006625 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006626 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006627 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006628 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6629 }
6630 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6631 }
6632 return OMX_ErrorNone;
6633}
6634
Shalaj Jain273b3e02012-06-22 19:08:03 -07006635int omx_vdec::async_message_process (void *context, void* message)
6636{
Arun Menon906de572013-06-18 17:01:40 -07006637 omx_vdec* omx = NULL;
6638 struct vdec_msginfo *vdec_msg = NULL;
6639 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6640 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6641 struct vdec_output_frameinfo *output_respbuf = NULL;
6642 int rc=1;
6643 if (context == NULL || message == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006644 DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
Arun Menon906de572013-06-18 17:01:40 -07006645 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006646 }
Arun Menon906de572013-06-18 17:01:40 -07006647 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006648
Arun Menon906de572013-06-18 17:01:40 -07006649 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006650
Arun Menon906de572013-06-18 17:01:40 -07006651 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006652
Arun Menon906de572013-06-18 17:01:40 -07006653 case VDEC_MSG_EVT_HW_ERROR:
6654 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6655 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6656 break;
6657
6658 case VDEC_MSG_RESP_START_DONE:
6659 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6660 OMX_COMPONENT_GENERATE_START_DONE);
6661 break;
6662
6663 case VDEC_MSG_RESP_STOP_DONE:
6664 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6665 OMX_COMPONENT_GENERATE_STOP_DONE);
6666 break;
6667
6668 case VDEC_MSG_RESP_RESUME_DONE:
6669 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6670 OMX_COMPONENT_GENERATE_RESUME_DONE);
6671 break;
6672
6673 case VDEC_MSG_RESP_PAUSE_DONE:
6674 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6675 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6676 break;
6677
6678 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6679 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6680 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6681 break;
6682 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6683 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6684 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6685 break;
6686 case VDEC_MSG_RESP_INPUT_FLUSHED:
6687 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6688
6689 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6690 vdec_msg->msgdata.input_frame_clientdata; */
6691
6692 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6693 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6694 if (omxhdr == NULL ||
Surajit Podderd2644d52013-08-28 17:59:06 +05306695 ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
Arun Menon906de572013-06-18 17:01:40 -07006696 omxhdr = NULL;
6697 vdec_msg->status_code = VDEC_S_EFATAL;
6698 }
6699 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6700 DEBUG_PRINT_HIGH("Unsupported input");
6701 omx->omx_report_error ();
6702 }
6703 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6704 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6705 }
6706 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6707 OMX_COMPONENT_GENERATE_EBD);
6708 break;
6709 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6710 int64_t *timestamp;
6711 timestamp = (int64_t *) malloc(sizeof(int64_t));
6712 if (timestamp) {
6713 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6714 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6715 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006716 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
Arun Menon906de572013-06-18 17:01:40 -07006717 vdec_msg->msgdata.output_frame.time_stamp);
6718 }
6719 break;
6720 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6721 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6722
6723 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6724 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6725 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6726 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6727 vdec_msg->msgdata.output_frame.pic_type);
6728
6729 if (omxhdr && omxhdr->pOutputPortPrivate &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306730 ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
Arun Menon906de572013-06-18 17:01:40 -07006731 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
Surajit Podderd2644d52013-08-28 17:59:06 +05306732 - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006733 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6734 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6735 }
Arun Menon906de572013-06-18 17:01:40 -07006736 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6737 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6738 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6739 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6740 omxhdr->nFlags = 0;
6741
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006742 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006743 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6744 //rc = -1;
6745 }
6746 if (omxhdr->nFilledLen) {
6747 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6748 }
6749 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6750 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6751 } else {
6752 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6753 }
6754 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6755 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6756 }
6757 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6758 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6759 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006760 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006761 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006762 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6763 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6764 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006765 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6766 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6767 omxhdr->nOffset);
6768 }
Arun Menon906de572013-06-18 17:01:40 -07006769 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6770 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006771 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006772 omx->time_stamp_dts.remove_time_stamp(
6773 omxhdr->nTimeStamp,
6774 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6775 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006776 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6777 OMX_COMPONENT_GENERATE_FTB);
6778 break;
6779 }
6780 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6781 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6782 }
6783 vdec_msg->msgdata.output_frame.bufferaddr =
6784 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6785 int format_notably_changed = 0;
6786 if (omxhdr->nFilledLen &&
Surajit Podderd2644d52013-08-28 17:59:06 +05306787 (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) {
Arun Menon906de572013-06-18 17:01:40 -07006788 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6789 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006790 DEBUG_PRINT_HIGH("Height/Width information has changed");
Arun Menon906de572013-06-18 17:01:40 -07006791 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6792 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6793 format_notably_changed = 1;
6794 }
6795 }
6796 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6797 vdec_msg->msgdata.output_frame.framesize.left)
6798 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6799 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6800 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6801 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6802 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6803 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6804 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006805 DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
Arun Menon906de572013-06-18 17:01:40 -07006806 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6807 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6808 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006809 DEBUG_PRINT_HIGH("Crop information changed. W: %lu --> %d, H: %lu -> %d",
Arun Menon906de572013-06-18 17:01:40 -07006810 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6811 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006812 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6813 omx->drv_ctx.video_resolution.frame_width) {
6814 vdec_msg->msgdata.output_frame.framesize.left = 0;
6815 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6816 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6817 }
6818 }
6819 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6820 omx->drv_ctx.video_resolution.frame_height) {
6821 vdec_msg->msgdata.output_frame.framesize.top = 0;
6822 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6823 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6824 }
6825 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006826 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 -07006827 vdec_msg->msgdata.output_frame.framesize.left,
6828 vdec_msg->msgdata.output_frame.framesize.top,
6829 vdec_msg->msgdata.output_frame.framesize.right,
6830 vdec_msg->msgdata.output_frame.framesize.bottom,
6831 omx->drv_ctx.video_resolution.frame_width,
6832 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006833 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6834 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6835 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6836 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6837 format_notably_changed = 1;
6838 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006839 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006840 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6841 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006842 if (format_notably_changed) {
6843 if (omx->is_video_session_supported()) {
Surajit Podderd2644d52013-08-28 17:59:06 +05306844 omx->post_event (0, vdec_msg->status_code,
Arun Menon906de572013-06-18 17:01:40 -07006845 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6846 } else {
6847 if (!omx->client_buffers.update_buffer_req()) {
6848 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6849 }
6850 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6851 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6852 }
6853 }
6854 if (omxhdr->nFilledLen)
6855 omx->prev_n_filled_len = omxhdr->nFilledLen;
6856
6857 output_respbuf = (struct vdec_output_frameinfo *)\
6858 omxhdr->pOutputPortPrivate;
6859 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6860 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6861 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6862 output_respbuf->pic_type = PICTURE_TYPE_I;
6863 }
6864 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6865 output_respbuf->pic_type = PICTURE_TYPE_P;
6866 }
6867 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6868 output_respbuf->pic_type = PICTURE_TYPE_B;
6869 }
6870
6871 if (omx->output_use_buffer)
6872 memcpy ( omxhdr->pBuffer, (void *)
6873 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6874 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6875 vdec_msg->msgdata.output_frame.len);
6876 } else
6877 omxhdr->nFilledLen = 0;
6878 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6879 OMX_COMPONENT_GENERATE_FBD);
6880 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6881 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6882 OMX_COMPONENT_GENERATE_EOS_DONE);
6883 else
6884 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6885 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6886 break;
6887 case VDEC_MSG_EVT_CONFIG_CHANGED:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006888 DEBUG_PRINT_HIGH("Port settings changed");
Arun Menon906de572013-06-18 17:01:40 -07006889 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6890 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6891 break;
6892 default:
6893 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006894 }
Arun Menon906de572013-06-18 17:01:40 -07006895 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006896}
6897
6898OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006899 OMX_HANDLETYPE hComp,
6900 OMX_BUFFERHEADERTYPE *buffer
6901 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006902{
Arun Menon906de572013-06-18 17:01:40 -07006903 unsigned address,p2,id;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006904 DEBUG_PRINT_LOW("Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006905
Arun Menon906de572013-06-18 17:01:40 -07006906 if (buffer == NULL) {
6907 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006908 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006909 DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6910 DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07006911 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6912
6913 /* return zero length and not an EOS buffer */
6914 /* return buffer if input flush in progress */
6915 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6916 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006917 DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
Arun Menon906de572013-06-18 17:01:40 -07006918 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6919 return OMX_ErrorNone;
6920 }
6921
6922 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006923 DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07006924 psource_frame = buffer;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006925 DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
Arun Menon906de572013-06-18 17:01:40 -07006926 push_input_buffer (hComp);
6927 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006928 DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
Arun Menon906de572013-06-18 17:01:40 -07006929 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6930 (unsigned)NULL)) {
6931 return OMX_ErrorBadParameter;
6932 }
6933 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006934
6935
Arun Menon906de572013-06-18 17:01:40 -07006936 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006937}
6938
6939OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6940{
Arun Menon906de572013-06-18 17:01:40 -07006941 unsigned address,p2,id;
6942 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006943
Arun Menon906de572013-06-18 17:01:40 -07006944 if (pdest_frame == NULL || psource_frame == NULL) {
6945 /*Check if we have a destination buffer*/
6946 if (pdest_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006947 DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07006948 if (m_input_free_q.m_size) {
6949 m_input_free_q.pop_entry(&address,&p2,&id);
6950 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6951 pdest_frame->nFilledLen = 0;
6952 pdest_frame->nTimeStamp = LLONG_MAX;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006953 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07006954 }
6955 }
6956
6957 /*Check if we have a destination buffer*/
6958 if (psource_frame == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006959 DEBUG_PRINT_LOW("Get a source buffer from the queue");
Arun Menon906de572013-06-18 17:01:40 -07006960 if (m_input_pending_q.m_size) {
6961 m_input_pending_q.pop_entry(&address,&p2,&id);
6962 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006963 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07006964 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006965 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07006966 psource_frame->nFlags,psource_frame->nFilledLen);
6967
6968 }
6969 }
6970
Shalaj Jain273b3e02012-06-22 19:08:03 -07006971 }
6972
Arun Menon906de572013-06-18 17:01:40 -07006973 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6974 switch (codec_type_parse) {
6975 case CODEC_TYPE_MPEG4:
6976 case CODEC_TYPE_H263:
6977 case CODEC_TYPE_MPEG2:
6978 ret = push_input_sc_codec(hComp);
6979 break;
6980 case CODEC_TYPE_H264:
6981 ret = push_input_h264(hComp);
6982 break;
6983 case CODEC_TYPE_VC1:
6984 ret = push_input_vc1(hComp);
6985 break;
6986 default:
6987 break;
6988 }
6989 if (ret != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07006990 DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
Arun Menon906de572013-06-18 17:01:40 -07006991 omx_report_error ();
6992 break;
6993 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006994 }
6995
Arun Menon906de572013-06-18 17:01:40 -07006996 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006997}
6998
6999OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7000{
Arun Menon906de572013-06-18 17:01:40 -07007001 OMX_U32 partial_frame = 1;
7002 OMX_BOOL generate_ebd = OMX_TRUE;
7003 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007004
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007005 DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
Arun Menon906de572013-06-18 17:01:40 -07007006 psource_frame,psource_frame->nTimeStamp);
7007 if (m_frame_parser.parse_sc_frame(psource_frame,
7008 pdest_frame,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007009 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007010 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007011 }
Arun Menon906de572013-06-18 17:01:40 -07007012
7013 if (partial_frame == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007014 DEBUG_PRINT_LOW("Frame size %lu source %p frame count %d",
Arun Menon906de572013-06-18 17:01:40 -07007015 pdest_frame->nFilledLen,psource_frame,frame_count);
7016
7017
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007018 DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
Arun Menon906de572013-06-18 17:01:40 -07007019 /*First Parsed buffer will have only header Hence skip*/
7020 if (frame_count == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007021 DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
Arun Menon906de572013-06-18 17:01:40 -07007022
7023 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
7024 codec_type_parse == CODEC_TYPE_DIVX) {
7025 mp4StreamType psBits;
7026 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7027 psBits.numBytes = pdest_frame->nFilledLen;
7028 mp4_headerparser.parseHeader(&psBits);
7029 }
7030
7031 frame_count++;
7032 } else {
7033 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7034 if (pdest_frame->nFilledLen) {
7035 /*Push the frame to the Decoder*/
7036 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7037 return OMX_ErrorBadParameter;
7038 }
7039 frame_count++;
7040 pdest_frame = NULL;
7041
7042 if (m_input_free_q.m_size) {
7043 m_input_free_q.pop_entry(&address,&p2,&id);
7044 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7045 pdest_frame->nFilledLen = 0;
7046 }
7047 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007048 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
Arun Menon906de572013-06-18 17:01:40 -07007049 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7050 (unsigned)NULL);
7051 pdest_frame = NULL;
7052 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007053 }
Arun Menon906de572013-06-18 17:01:40 -07007054 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007055 DEBUG_PRINT_LOW("Not a Complete Frame %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007056 /*Check if Destination Buffer is full*/
7057 if (pdest_frame->nAllocLen ==
7058 pdest_frame->nFilledLen + pdest_frame->nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007059 DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007060 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007061 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007062 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007063
Arun Menon906de572013-06-18 17:01:40 -07007064 if (psource_frame->nFilledLen == 0) {
7065 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7066 if (pdest_frame) {
7067 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007068 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %lld",
Arun Menon906de572013-06-18 17:01:40 -07007069 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007070 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007071 pdest_frame->nFilledLen,frame_count++);
7072 /*Push the frame to the Decoder*/
7073 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7074 return OMX_ErrorBadParameter;
7075 }
7076 frame_count++;
7077 pdest_frame = NULL;
7078 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007079 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
Arun Menon906de572013-06-18 17:01:40 -07007080 generate_ebd = OMX_FALSE;
7081 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007082 }
Arun Menon906de572013-06-18 17:01:40 -07007083 if (generate_ebd) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007084 DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007085 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7086 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007087
Arun Menon906de572013-06-18 17:01:40 -07007088 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007089 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007090 m_input_pending_q.pop_entry(&address,&p2,&id);
7091 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007092 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
Arun Menon906de572013-06-18 17:01:40 -07007093 psource_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007094 DEBUG_PRINT_LOW("Next source Buffer flag %lu length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007095 psource_frame->nFlags,psource_frame->nFilledLen);
7096 }
7097 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007098 }
Arun Menon906de572013-06-18 17:01:40 -07007099 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007100}
7101
7102OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7103{
Arun Menon906de572013-06-18 17:01:40 -07007104 OMX_U32 partial_frame = 1;
7105 unsigned address = 0, p2 = 0, id = 0;
7106 OMX_BOOL isNewFrame = OMX_FALSE;
7107 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007108
Arun Menon906de572013-06-18 17:01:40 -07007109 if (h264_scratch.pBuffer == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007110 DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
Arun Menon906de572013-06-18 17:01:40 -07007111 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007112 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007113 DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %lu "
Arun Menon906de572013-06-18 17:01:40 -07007114 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007115 DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007116 if (h264_scratch.nFilledLen && look_ahead_nal) {
7117 look_ahead_nal = false;
7118 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7119 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007120 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7121 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7122 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007123 DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007124 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007125 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007126 DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007127 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007128 }
Arun Menon906de572013-06-18 17:01:40 -07007129 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007130
7131 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7132 in EOS flag getting associated with the destination
7133 */
7134 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7135 pdest_frame->nFilledLen) {
7136 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7137 generate_ebd = OMX_FALSE;
7138 }
7139
Arun Menon906de572013-06-18 17:01:40 -07007140 if (nal_length == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007141 DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
Arun Menon906de572013-06-18 17:01:40 -07007142 if (m_frame_parser.parse_sc_frame(psource_frame,
7143 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007144 DEBUG_PRINT_ERROR("Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007145 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007146 }
Arun Menon906de572013-06-18 17:01:40 -07007147 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007148 DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
Arun Menon906de572013-06-18 17:01:40 -07007149 if (m_frame_parser.parse_h264_nallength(psource_frame,
7150 &h264_scratch,&partial_frame) == -1) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007151 DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
Arun Menon906de572013-06-18 17:01:40 -07007152 return OMX_ErrorBadParameter;
7153 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007154 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007155
Arun Menon906de572013-06-18 17:01:40 -07007156 if (partial_frame == 0) {
7157 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007158 DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
Arun Menon906de572013-06-18 17:01:40 -07007159 nal_count++;
7160 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7161 h264_scratch.nFlags = psource_frame->nFlags;
7162 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007163 DEBUG_PRINT_LOW("Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007164 if (h264_scratch.nFilledLen) {
7165 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7166 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007167#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007168 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7169 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7170 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7171 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7172 // If timeinfo is present frame info from SEI is already processed
7173 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7174 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007175#endif
Arun Menon906de572013-06-18 17:01:40 -07007176 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7177 nal_count++;
7178 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7179 pdest_frame->nTimeStamp = h264_last_au_ts;
7180 pdest_frame->nFlags = h264_last_au_flags;
7181#ifdef PANSCAN_HDLR
7182 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7183 h264_parser->update_panscan_data(h264_last_au_ts);
7184#endif
7185 }
7186 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7187 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7188 h264_last_au_ts = h264_scratch.nTimeStamp;
7189 h264_last_au_flags = h264_scratch.nFlags;
7190#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7191 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7192 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7193 if (!VALID_TS(h264_last_au_ts))
7194 h264_last_au_ts = ts_in_sei;
7195 }
7196#endif
7197 } else
7198 h264_last_au_ts = LLONG_MAX;
7199 }
7200
7201 if (!isNewFrame) {
7202 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7203 h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007204 DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %lu",
Arun Menon906de572013-06-18 17:01:40 -07007205 h264_scratch.nFilledLen);
7206 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7207 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7208 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7209 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7210 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7211 h264_scratch.nFilledLen = 0;
7212 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007213 DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007214 return OMX_ErrorBadParameter;
7215 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007216 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007217 look_ahead_nal = true;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007218 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007219 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007220 DEBUG_PRINT_LOW("Found a frame size = %lu number = %d",
Arun Menon906de572013-06-18 17:01:40 -07007221 pdest_frame->nFilledLen,frame_count++);
7222
7223 if (pdest_frame->nFilledLen == 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007224 DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
Arun Menon906de572013-06-18 17:01:40 -07007225 look_ahead_nal = false;
7226 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7227 h264_scratch.nFilledLen) {
7228 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7229 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7230 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7231 h264_scratch.nFilledLen = 0;
7232 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007233 DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007234 return OMX_ErrorBadParameter;
7235 }
7236 } else {
7237 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007238 DEBUG_PRINT_LOW("Reset the EOS Flag");
Arun Menon906de572013-06-18 17:01:40 -07007239 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7240 }
7241 /*Push the frame to the Decoder*/
7242 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7243 return OMX_ErrorBadParameter;
7244 }
7245 //frame_count++;
7246 pdest_frame = NULL;
7247 if (m_input_free_q.m_size) {
7248 m_input_free_q.pop_entry(&address,&p2,&id);
7249 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007250 DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
Arun Menon906de572013-06-18 17:01:40 -07007251 pdest_frame->nFilledLen = 0;
7252 pdest_frame->nFlags = 0;
7253 pdest_frame->nTimeStamp = LLONG_MAX;
7254 }
7255 }
7256 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007257 }
Arun Menon906de572013-06-18 17:01:40 -07007258 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007259 DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Arun Menon906de572013-06-18 17:01:40 -07007260 /*Check if Destination Buffer is full*/
7261 if (h264_scratch.nAllocLen ==
7262 h264_scratch.nFilledLen + h264_scratch.nOffset) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007263 DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
Arun Menon906de572013-06-18 17:01:40 -07007264 return OMX_ErrorStreamCorrupt;
7265 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007266 }
Arun Menon906de572013-06-18 17:01:40 -07007267
7268 if (!psource_frame->nFilledLen) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007269 DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007270
7271 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7272 if (pdest_frame) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007273 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
Arun Menon906de572013-06-18 17:01:40 -07007274 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7275 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007276 if(pdest_frame->nFilledLen == 0) {
7277 /* No residual frame from before, send whatever
7278 * we have left */
7279 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7280 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7281 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7282 h264_scratch.nFilledLen = 0;
7283 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7284 } else {
7285 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7286 if(!isNewFrame) {
7287 /* Have a residual frame, but we know that the
7288 * AU in this frame is belonging to whatever
7289 * frame we had left over. So append it */
7290 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7291 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7292 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7293 h264_scratch.nFilledLen = 0;
7294 pdest_frame->nTimeStamp = h264_last_au_ts;
7295 } else {
7296 /* Completely new frame, let's just push what
7297 * we have now. The resulting EBD would trigger
7298 * another push */
7299 generate_ebd = OMX_FALSE;
7300 pdest_frame->nTimeStamp = h264_last_au_ts;
7301 h264_last_au_ts = h264_scratch.nTimeStamp;
7302 }
7303 }
Arun Menon906de572013-06-18 17:01:40 -07007304 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007305 DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
Arun Menon906de572013-06-18 17:01:40 -07007306 return OMX_ErrorBadParameter;
7307 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007308
7309 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7310 if(generate_ebd == OMX_TRUE) {
7311 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7312 }
Arun Menon906de572013-06-18 17:01:40 -07007313
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007314 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007315 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007316 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
Arun Menon906de572013-06-18 17:01:40 -07007317#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7318 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7319 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7320 if (!VALID_TS(pdest_frame->nTimeStamp))
7321 pdest_frame->nTimeStamp = ts_in_sei;
7322 }
7323#endif
7324 /*Push the frame to the Decoder*/
7325 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7326 return OMX_ErrorBadParameter;
7327 }
7328 frame_count++;
7329 pdest_frame = NULL;
7330 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007331 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu",
Arun Menon906de572013-06-18 17:01:40 -07007332 pdest_frame,h264_scratch.nFilledLen);
7333 generate_ebd = OMX_FALSE;
7334 }
7335 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007336 }
Arun Menon906de572013-06-18 17:01:40 -07007337 if (generate_ebd && !psource_frame->nFilledLen) {
7338 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7339 psource_frame = NULL;
7340 if (m_input_pending_q.m_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007341 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
Arun Menon906de572013-06-18 17:01:40 -07007342 m_input_pending_q.pop_entry(&address,&p2,&id);
7343 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007344 DEBUG_PRINT_LOW("Next source Buffer flag %lu src length %lu",
Arun Menon906de572013-06-18 17:01:40 -07007345 psource_frame->nFlags,psource_frame->nFilledLen);
7346 }
7347 }
7348 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007349}
7350
7351OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7352{
7353 OMX_U8 *buf, *pdest;
7354 OMX_U32 partial_frame = 1;
7355 OMX_U32 buf_len, dest_len;
7356
Arun Menon906de572013-06-18 17:01:40 -07007357 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007358 first_frame = 1;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007359 DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
Arun Menon906de572013-06-18 17:01:40 -07007360 if (!m_vendor_config.pData) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007361 DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007362 buf = psource_frame->pBuffer;
7363 buf_len = psource_frame->nFilledLen;
7364
7365 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007366 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007367 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007368 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007369 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007370 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007371 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007372 return OMX_ErrorStreamCorrupt;
7373 }
Arun Menon906de572013-06-18 17:01:40 -07007374 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007375 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7376 pdest_frame->nOffset;
7377 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007378 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007379
Arun Menon906de572013-06-18 17:01:40 -07007380 if (dest_len < m_vendor_config.nDataSize) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007381 DEBUG_PRINT_ERROR("Destination buffer full");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007382 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007383 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007384 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7385 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7386 }
7387 }
7388 }
7389
Arun Menon906de572013-06-18 17:01:40 -07007390 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007391 case VC1_AP:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007392 DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007393 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007394 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007395 return OMX_ErrorBadParameter;
7396 }
Arun Menon906de572013-06-18 17:01:40 -07007397 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007398
7399 case VC1_SP_MP_RCV:
7400 default:
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007401 DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007402 return OMX_ErrorBadParameter;
7403 }
7404 return OMX_ErrorNone;
7405}
7406
David Ng38e2d232013-03-15 20:05:58 -07007407#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007408bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007409 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007410{
Arun Menon906de572013-06-18 17:01:40 -07007411 struct pmem_allocation allocation;
7412 allocation.size = buffer_size;
7413 allocation.align = clip2(alignment);
7414 if (allocation.align < 4096) {
7415 allocation.align = 4096;
7416 }
7417 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007418 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
Arun Menon906de572013-06-18 17:01:40 -07007419 allocation.align, allocation.size);
7420 return false;
7421 }
7422 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007423}
David Ng38e2d232013-03-15 20:05:58 -07007424#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007425#ifdef USE_ION
7426int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007427 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7428 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007429{
Arun Menon906de572013-06-18 17:01:40 -07007430 int fd = -EINVAL;
7431 int rc = -EINVAL;
7432 int ion_dev_flag;
7433 struct vdec_ion ion_buf_info;
7434 if (!alloc_data || buffer_size <= 0 || !fd_data) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007435 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
Arun Menon906de572013-06-18 17:01:40 -07007436 return -EINVAL;
7437 }
7438 ion_dev_flag = O_RDONLY;
7439 fd = open (MEM_DEVICE, ion_dev_flag);
7440 if (fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007441 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
Arun Menon906de572013-06-18 17:01:40 -07007442 return fd;
7443 }
7444 alloc_data->flags = 0;
7445 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7446 alloc_data->flags |= ION_FLAG_CACHED;
7447 }
7448 alloc_data->len = buffer_size;
7449 alloc_data->align = clip2(alignment);
7450 if (alloc_data->align < 4096) {
7451 alloc_data->align = 4096;
7452 }
7453 if ((secure_mode) && (flag & ION_SECURE))
7454 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007455
Arun Menon906de572013-06-18 17:01:40 -07007456 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05307457 if (secure_mode && (alloc_data->flags & ION_SECURE))
Arun Menon906de572013-06-18 17:01:40 -07007458 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7459 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7460 if (rc || !alloc_data->handle) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007461 DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
Arun Menon906de572013-06-18 17:01:40 -07007462 alloc_data->handle = NULL;
7463 close(fd);
7464 fd = -ENOMEM;
7465 return fd;
7466 }
7467 fd_data->handle = alloc_data->handle;
7468 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7469 if (rc) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007470 DEBUG_PRINT_ERROR("ION MAP failed ");
Arun Menon906de572013-06-18 17:01:40 -07007471 ion_buf_info.ion_alloc_data = *alloc_data;
7472 ion_buf_info.ion_device_fd = fd;
7473 ion_buf_info.fd_ion_data = *fd_data;
7474 free_ion_memory(&ion_buf_info);
7475 fd_data->fd =-1;
Arun Menon906de572013-06-18 17:01:40 -07007476 fd = -ENOMEM;
7477 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007478
Arun Menon906de572013-06-18 17:01:40 -07007479 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007480}
7481
Arun Menon906de572013-06-18 17:01:40 -07007482void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7483{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007484
Arun Menon906de572013-06-18 17:01:40 -07007485 if (!buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007486 DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
Arun Menon906de572013-06-18 17:01:40 -07007487 return;
7488 }
7489 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7490 &buf_ion_info->ion_alloc_data.handle)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007491 DEBUG_PRINT_ERROR("ION: free failed" );
Arun Menon906de572013-06-18 17:01:40 -07007492 }
7493 close(buf_ion_info->ion_device_fd);
7494 buf_ion_info->ion_device_fd = -1;
7495 buf_ion_info->ion_alloc_data.handle = NULL;
7496 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007497}
7498#endif
7499void omx_vdec::free_output_buffer_header()
7500{
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007501 DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
Arun Menon906de572013-06-18 17:01:40 -07007502 output_use_buffer = false;
7503 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007504
Arun Menon906de572013-06-18 17:01:40 -07007505 if (m_out_mem_ptr) {
7506 free (m_out_mem_ptr);
7507 m_out_mem_ptr = NULL;
7508 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007509
Arun Menon906de572013-06-18 17:01:40 -07007510 if (m_platform_list) {
7511 free(m_platform_list);
7512 m_platform_list = NULL;
7513 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007514
Arun Menon906de572013-06-18 17:01:40 -07007515 if (drv_ctx.ptr_respbuffer) {
7516 free (drv_ctx.ptr_respbuffer);
7517 drv_ctx.ptr_respbuffer = NULL;
7518 }
7519 if (drv_ctx.ptr_outputbuffer) {
7520 free (drv_ctx.ptr_outputbuffer);
7521 drv_ctx.ptr_outputbuffer = NULL;
7522 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007523#ifdef USE_ION
7524 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007525 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007526 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007527 drv_ctx.op_buf_ion_info = NULL;
7528 }
7529#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007530 if (out_dynamic_list) {
7531 free(out_dynamic_list);
7532 out_dynamic_list = NULL;
7533 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007534}
7535
7536void omx_vdec::free_input_buffer_header()
7537{
7538 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007539 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007540 if (m_inp_heap_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007541 DEBUG_PRINT_LOW("Free input Heap Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007542 free (m_inp_heap_ptr);
7543 m_inp_heap_ptr = NULL;
7544 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007545
Arun Menon906de572013-06-18 17:01:40 -07007546 if (m_phdr_pmem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007547 DEBUG_PRINT_LOW("Free input pmem header Pointer");
Arun Menon906de572013-06-18 17:01:40 -07007548 free (m_phdr_pmem_ptr);
7549 m_phdr_pmem_ptr = NULL;
7550 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007551 }
Arun Menon906de572013-06-18 17:01:40 -07007552 if (m_inp_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007553 DEBUG_PRINT_LOW("Free input pmem Pointer area");
Arun Menon906de572013-06-18 17:01:40 -07007554 free (m_inp_mem_ptr);
7555 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007556 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007557 /* We just freed all the buffer headers, every thing in m_input_free_q,
7558 * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007559 while (m_input_free_q.m_size) {
7560 unsigned address, p2, id;
7561 m_input_free_q.pop_entry(&address, &p2, &id);
7562 }
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07007563 while (m_input_pending_q.m_size) {
7564 unsigned address, p2, id;
7565 m_input_pending_q.pop_entry(&address, &p2, &id);
7566 }
7567 pdest_frame = NULL;
7568 psource_frame = NULL;
Arun Menon906de572013-06-18 17:01:40 -07007569 if (drv_ctx.ptr_inputbuffer) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007570 DEBUG_PRINT_LOW("Free Driver Context pointer");
Arun Menon906de572013-06-18 17:01:40 -07007571 free (drv_ctx.ptr_inputbuffer);
7572 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007573 }
7574#ifdef USE_ION
7575 if (drv_ctx.ip_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007576 DEBUG_PRINT_LOW("Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007577 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007578 drv_ctx.ip_buf_ion_info = NULL;
7579 }
7580#endif
7581}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007582
7583int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007584{
Arun Menon906de572013-06-18 17:01:40 -07007585 enum v4l2_buf_type btype;
7586 int rc = 0;
7587 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007588
Arun Menon906de572013-06-18 17:01:40 -07007589 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7590 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7591 v4l2_port = OUTPUT_PORT;
7592 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7593 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7594 v4l2_port = CAPTURE_PORT;
7595 } else if (port == OMX_ALL) {
7596 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7597 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007598
Arun Menon906de572013-06-18 17:01:40 -07007599 if (!rc_input)
7600 return rc_input;
7601 else
7602 return rc_output;
7603 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007604
Arun Menon906de572013-06-18 17:01:40 -07007605 if (!streaming[v4l2_port]) {
7606 // already streamed off, warn and move on
7607 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7608 " which is already streamed off", v4l2_port);
7609 return 0;
7610 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007611
Arun Menon906de572013-06-18 17:01:40 -07007612 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007613
Arun Menon906de572013-06-18 17:01:40 -07007614 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7615 if (rc) {
7616 /*TODO: How to handle this case */
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007617 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
Arun Menon906de572013-06-18 17:01:40 -07007618 } else {
7619 streaming[v4l2_port] = false;
7620 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007621
Arun Menon906de572013-06-18 17:01:40 -07007622 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007623}
7624
7625OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7626{
Arun Menon906de572013-06-18 17:01:40 -07007627 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7628 struct v4l2_requestbuffers bufreq;
7629 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7630 struct v4l2_format fmt;
7631 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007632 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007633 buffer_prop->actualcount, buffer_prop->buffer_size);
7634 bufreq.memory = V4L2_MEMORY_USERPTR;
7635 bufreq.count = 1;
7636 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7637 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7638 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7639 fmt.fmt.pix_mp.pixelformat = output_capability;
7640 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7641 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7642 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7643 fmt.fmt.pix_mp.pixelformat = capture_capability;
7644 } else {
7645 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007646 }
Arun Menon906de572013-06-18 17:01:40 -07007647 if (eRet==OMX_ErrorNone) {
7648 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007649 }
Arun Menon906de572013-06-18 17:01:40 -07007650 if (ret) {
7651 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7652 /*TODO: How to handle this case */
7653 eRet = OMX_ErrorInsufficientResources;
7654 return eRet;
7655 } else {
7656 buffer_prop->actualcount = bufreq.count;
7657 buffer_prop->mincount = bufreq.count;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007658 DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007659 }
Arun Menon906de572013-06-18 17:01:40 -07007660 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7661 buffer_prop->actualcount, buffer_prop->buffer_size);
7662
7663 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7664 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7665
7666 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7667
7668 update_resolution(fmt.fmt.pix_mp.width,
7669 fmt.fmt.pix_mp.height,
7670 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7671 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7672 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7673 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007674 DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Arun Menon906de572013-06-18 17:01:40 -07007675
7676 if (ret) {
7677 /*TODO: How to handle this case */
7678 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7679 eRet = OMX_ErrorInsufficientResources;
7680 } else {
7681 int extra_idx = 0;
7682
7683 eRet = is_video_session_supported();
7684 if (eRet)
7685 return eRet;
7686
7687 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7688 buf_size = buffer_prop->buffer_size;
7689 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7690 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7691 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7692 } else if (extra_idx >= VIDEO_MAX_PLANES) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007693 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
Arun Menon906de572013-06-18 17:01:40 -07007694 return OMX_ErrorBadParameter;
7695 }
7696 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7697 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7698 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7699 }
7700 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7701 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7702 }
7703 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7704 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007705 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d",
Arun Menon906de572013-06-18 17:01:40 -07007706 client_extra_data_size);
7707 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05307708 if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
7709 client_extra_data_size += OMX_FRAMEPACK_EXTRADATA_SIZE;
7710 DEBUG_PRINT_HIGH("framepack extradata enabled");
7711 }
Arun Menon906de572013-06-18 17:01:40 -07007712 if (client_extra_data_size) {
7713 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7714 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7715 }
7716 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7717 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7718 drv_ctx.extradata_info.buffer_size = extra_data_size;
7719 buf_size += client_extra_data_size;
7720 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7721 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7722 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7723 if (in_reconfig) // BufReq will be set to driver when port is disabled
7724 buffer_prop->buffer_size = buf_size;
7725 else if (buf_size != buffer_prop->buffer_size) {
7726 buffer_prop->buffer_size = buf_size;
7727 eRet = set_buffer_req(buffer_prop);
7728 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007729 }
Arun Menon906de572013-06-18 17:01:40 -07007730 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7731 buffer_prop->actualcount, buffer_prop->buffer_size);
7732 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007733}
7734
7735OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7736{
Arun Menon906de572013-06-18 17:01:40 -07007737 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7738 unsigned buf_size = 0;
7739 struct v4l2_format fmt;
7740 struct v4l2_requestbuffers bufreq;
7741 int ret;
7742 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7743 buffer_prop->actualcount, buffer_prop->buffer_size);
7744 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7745 if (buf_size != buffer_prop->buffer_size) {
7746 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7747 buffer_prop->buffer_size, buf_size);
7748 eRet = OMX_ErrorBadParameter;
7749 } else {
7750 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7751 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007752
Arun Menon906de572013-06-18 17:01:40 -07007753 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7754 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7755 fmt.fmt.pix_mp.pixelformat = output_capability;
Shalaj Jaind3902bb2013-10-07 12:42:55 -07007756 fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
Arun Menon906de572013-06-18 17:01:40 -07007757 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7758 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7759 fmt.fmt.pix_mp.pixelformat = capture_capability;
7760 } else {
7761 eRet = OMX_ErrorBadParameter;
7762 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007763
Arun Menon906de572013-06-18 17:01:40 -07007764 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7765 if (ret) {
7766 /*TODO: How to handle this case */
7767 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7768 eRet = OMX_ErrorInsufficientResources;
7769 }
7770
7771 bufreq.memory = V4L2_MEMORY_USERPTR;
7772 bufreq.count = buffer_prop->actualcount;
7773 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7774 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7775 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7776 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7777 } else {
7778 eRet = OMX_ErrorBadParameter;
7779 }
7780
7781 if (eRet==OMX_ErrorNone) {
7782 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7783 }
7784
7785 if (ret) {
7786 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7787 /*TODO: How to handle this case */
7788 eRet = OMX_ErrorInsufficientResources;
7789 } else if (bufreq.count < buffer_prop->actualcount) {
7790 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7791 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7792 buffer_prop->actualcount, bufreq.count);
7793 eRet = OMX_ErrorInsufficientResources;
7794 } else {
7795 if (!client_buffers.update_buffer_req()) {
7796 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7797 eRet = OMX_ErrorInsufficientResources;
7798 }
7799 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007800 }
Arun Menon906de572013-06-18 17:01:40 -07007801 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007802}
7803
Shalaj Jain273b3e02012-06-22 19:08:03 -07007804OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7805{
Arun Menon906de572013-06-18 17:01:40 -07007806 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7807 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007808}
7809
7810OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7811{
Arun Menon906de572013-06-18 17:01:40 -07007812 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7813 if (!portDefn) {
7814 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007815 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007816 DEBUG_PRINT_LOW("omx_vdec::update_portdef");
Arun Menon906de572013-06-18 17:01:40 -07007817 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7818 portDefn->nSize = sizeof(portDefn);
7819 portDefn->eDomain = OMX_PortDomainVideo;
7820 if (drv_ctx.frame_rate.fps_denominator > 0)
7821 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7822 drv_ctx.frame_rate.fps_denominator;
7823 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007824 DEBUG_PRINT_ERROR("Error: Divide by zero");
Arun Menon906de572013-06-18 17:01:40 -07007825 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007826 }
Arun Menon906de572013-06-18 17:01:40 -07007827 if (0 == portDefn->nPortIndex) {
7828 portDefn->eDir = OMX_DirInput;
7829 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7830 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7831 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7832 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7833 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7834 portDefn->bEnabled = m_inp_bEnabled;
7835 portDefn->bPopulated = m_inp_bPopulated;
7836 } else if (1 == portDefn->nPortIndex) {
7837 unsigned int buf_size = 0;
7838 if (!client_buffers.update_buffer_req()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007839 DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
Arun Menon906de572013-06-18 17:01:40 -07007840 return OMX_ErrorHardware;
7841 }
7842 if (!client_buffers.get_buffer_req(buf_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007843 DEBUG_PRINT_ERROR("update buffer requirements");
Arun Menon906de572013-06-18 17:01:40 -07007844 return OMX_ErrorHardware;
7845 }
7846 portDefn->nBufferSize = buf_size;
7847 portDefn->eDir = OMX_DirOutput;
7848 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7849 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7850 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7851 portDefn->bEnabled = m_out_bEnabled;
7852 portDefn->bPopulated = m_out_bPopulated;
7853 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007854 DEBUG_PRINT_ERROR("Error in getting color format");
Arun Menon906de572013-06-18 17:01:40 -07007855 return OMX_ErrorHardware;
7856 }
7857 } else {
7858 portDefn->eDir = OMX_DirMax;
7859 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7860 (int)portDefn->nPortIndex);
7861 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007862 }
Arun Menon906de572013-06-18 17:01:40 -07007863 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7864 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7865 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7866 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7867 DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007868 " SliceHeight = %lu", portDefn->format.video.nFrameWidth,
Arun Menon906de572013-06-18 17:01:40 -07007869 portDefn->format.video.nFrameHeight,
7870 portDefn->format.video.nStride,
7871 portDefn->format.video.nSliceHeight);
7872 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007873
7874}
7875
7876OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7877{
Arun Menon906de572013-06-18 17:01:40 -07007878 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7879 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7880 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007881
Arun Menon906de572013-06-18 17:01:40 -07007882 if (!m_out_mem_ptr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007883 DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
Arun Menon906de572013-06-18 17:01:40 -07007884 int nBufHdrSize = 0;
7885 int nPlatformEntrySize = 0;
7886 int nPlatformListSize = 0;
7887 int nPMEMInfoSize = 0;
7888 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7889 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7890 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007891
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007892 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007893 drv_ctx.op_buf.actualcount);
7894 nBufHdrSize = drv_ctx.op_buf.actualcount *
7895 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007896
Arun Menon906de572013-06-18 17:01:40 -07007897 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7898 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7899 nPlatformListSize = drv_ctx.op_buf.actualcount *
7900 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7901 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7902 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007903
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007904 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
Arun Menon906de572013-06-18 17:01:40 -07007905 sizeof(OMX_BUFFERHEADERTYPE),
7906 nPMEMInfoSize,
7907 nPlatformListSize);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007908 DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize,
Arun Menon906de572013-06-18 17:01:40 -07007909 m_out_bm_count);
7910 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7911 // Alloc mem for platform specific info
7912 char *pPtr=NULL;
7913 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7914 nPMEMInfoSize,1);
7915 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7916 calloc (sizeof(struct vdec_bufferpayload),
7917 drv_ctx.op_buf.actualcount);
7918 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7919 calloc (sizeof (struct vdec_output_frameinfo),
7920 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007921#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007922 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7923 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007924#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007925 if (dynamic_buf_mode) {
7926 out_dynamic_list = (struct dynamic_buf_list *) \
7927 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
7928 }
Arun Menon906de572013-06-18 17:01:40 -07007929 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7930 && drv_ctx.ptr_respbuffer) {
7931 bufHdr = m_out_mem_ptr;
7932 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7933 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7934 (((char *) m_platform_list) + nPlatformListSize);
7935 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7936 (((char *) m_platform_entry) + nPlatformEntrySize);
7937 pPlatformList = m_platform_list;
7938 pPlatformEntry = m_platform_entry;
7939 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007940
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007941 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007942
Arun Menon906de572013-06-18 17:01:40 -07007943 // Settting the entire storage nicely
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007944 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
Arun Menon906de572013-06-18 17:01:40 -07007945 m_out_mem_ptr,pPlatformEntry);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007946 DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
Arun Menon906de572013-06-18 17:01:40 -07007947 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7948 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7949 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7950 // Set the values when we determine the right HxW param
7951 bufHdr->nAllocLen = 0;
7952 bufHdr->nFilledLen = 0;
7953 bufHdr->pAppPrivate = NULL;
7954 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7955 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7956 pPlatformEntry->entry = pPMEMInfo;
7957 // Initialize the Platform List
7958 pPlatformList->nEntries = 1;
7959 pPlatformList->entryList = pPlatformEntry;
7960 // Keep pBuffer NULL till vdec is opened
7961 bufHdr->pBuffer = NULL;
7962 pPMEMInfo->offset = 0;
7963 pPMEMInfo->pmem_fd = 0;
7964 bufHdr->pPlatformPrivate = pPlatformList;
7965 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007966#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007967 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007968#endif
Arun Menon906de572013-06-18 17:01:40 -07007969 /*Create a mapping between buffers*/
7970 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7971 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7972 &drv_ctx.ptr_outputbuffer[i];
7973 // Move the buffer and buffer header pointers
7974 bufHdr++;
7975 pPMEMInfo++;
7976 pPlatformEntry++;
7977 pPlatformList++;
7978 }
7979 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07007980 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
Arun Menon906de572013-06-18 17:01:40 -07007981 m_out_mem_ptr, pPtr);
7982 if (m_out_mem_ptr) {
7983 free(m_out_mem_ptr);
7984 m_out_mem_ptr = NULL;
7985 }
7986 if (pPtr) {
7987 free(pPtr);
7988 pPtr = NULL;
7989 }
7990 if (drv_ctx.ptr_outputbuffer) {
7991 free(drv_ctx.ptr_outputbuffer);
7992 drv_ctx.ptr_outputbuffer = NULL;
7993 }
7994 if (drv_ctx.ptr_respbuffer) {
7995 free(drv_ctx.ptr_respbuffer);
7996 drv_ctx.ptr_respbuffer = NULL;
7997 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007998#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007999 if (drv_ctx.op_buf_ion_info) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008000 DEBUG_PRINT_LOW("Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07008001 free(drv_ctx.op_buf_ion_info);
8002 drv_ctx.op_buf_ion_info = NULL;
8003 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008004#endif
Arun Menon906de572013-06-18 17:01:40 -07008005 eRet = OMX_ErrorInsufficientResources;
8006 }
8007 } else {
8008 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008009 }
Arun Menon906de572013-06-18 17:01:40 -07008010 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008011}
8012
8013void omx_vdec::complete_pending_buffer_done_cbs()
8014{
Arun Menon906de572013-06-18 17:01:40 -07008015 unsigned p1;
8016 unsigned p2;
8017 unsigned ident;
8018 omx_cmd_queue tmp_q, pending_bd_q;
8019 pthread_mutex_lock(&m_lock);
8020 // pop all pending GENERATE FDB from ftb queue
8021 while (m_ftb_q.m_size) {
8022 m_ftb_q.pop_entry(&p1,&p2,&ident);
8023 if (ident == OMX_COMPONENT_GENERATE_FBD) {
8024 pending_bd_q.insert_entry(p1,p2,ident);
8025 } else {
8026 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008027 }
Arun Menon906de572013-06-18 17:01:40 -07008028 }
8029 //return all non GENERATE FDB to ftb queue
8030 while (tmp_q.m_size) {
8031 tmp_q.pop_entry(&p1,&p2,&ident);
8032 m_ftb_q.insert_entry(p1,p2,ident);
8033 }
8034 // pop all pending GENERATE EDB from etb queue
8035 while (m_etb_q.m_size) {
8036 m_etb_q.pop_entry(&p1,&p2,&ident);
8037 if (ident == OMX_COMPONENT_GENERATE_EBD) {
8038 pending_bd_q.insert_entry(p1,p2,ident);
8039 } else {
8040 tmp_q.insert_entry(p1,p2,ident);
8041 }
8042 }
8043 //return all non GENERATE FDB to etb queue
8044 while (tmp_q.m_size) {
8045 tmp_q.pop_entry(&p1,&p2,&ident);
8046 m_etb_q.insert_entry(p1,p2,ident);
8047 }
8048 pthread_mutex_unlock(&m_lock);
8049 // process all pending buffer dones
8050 while (pending_bd_q.m_size) {
8051 pending_bd_q.pop_entry(&p1,&p2,&ident);
8052 switch (ident) {
8053 case OMX_COMPONENT_GENERATE_EBD:
8054 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008055 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008056 omx_report_error ();
8057 }
8058 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008059
Arun Menon906de572013-06-18 17:01:40 -07008060 case OMX_COMPONENT_GENERATE_FBD:
8061 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008062 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
Arun Menon906de572013-06-18 17:01:40 -07008063 omx_report_error ();
8064 }
8065 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008066 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008067 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008068}
8069
8070void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8071{
Arun Menon906de572013-06-18 17:01:40 -07008072 OMX_U32 new_frame_interval = 0;
8073 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8074 && llabs(act_timestamp - prev_ts) > 2000) {
8075 new_frame_interval = client_set_fps ? frm_int :
8076 llabs(act_timestamp - prev_ts);
8077 if (new_frame_interval < frm_int || frm_int == 0) {
8078 frm_int = new_frame_interval;
8079 if (frm_int) {
8080 drv_ctx.frame_rate.fps_numerator = 1e6;
8081 drv_ctx.frame_rate.fps_denominator = frm_int;
8082 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
8083 frm_int, drv_ctx.frame_rate.fps_numerator /
8084 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008085
Arun Menon906de572013-06-18 17:01:40 -07008086 /* We need to report the difference between this FBD and the previous FBD
8087 * back to the driver for clock scaling purposes. */
8088 struct v4l2_outputparm oparm;
8089 /*XXX: we're providing timing info as seconds per frame rather than frames
8090 * per second.*/
8091 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
8092 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008093
Arun Menon906de572013-06-18 17:01:40 -07008094 struct v4l2_streamparm sparm;
8095 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
8096 sparm.parm.output = oparm;
8097 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
8098 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
8099 performance might be affected");
8100 }
8101
8102 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07008103 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008104 }
Arun Menon906de572013-06-18 17:01:40 -07008105 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008106}
8107
8108void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8109{
Arun Menon906de572013-06-18 17:01:40 -07008110 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8111 prev_ts = act_timestamp;
8112 rst_prev_ts = false;
8113 } else if (VALID_TS(prev_ts)) {
8114 bool codec_cond = (drv_ctx.timestamp_adjust)?
8115 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8116 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8117 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8118 if (frm_int > 0 && codec_cond) {
8119 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8120 act_timestamp = prev_ts + frm_int;
8121 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8122 prev_ts = act_timestamp;
8123 } else
8124 set_frame_rate(act_timestamp);
8125 } else if (frm_int > 0) // In this case the frame rate was set along
8126 { // with the port definition, start ts with 0
8127 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8128 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008129 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008130}
8131
8132void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8133{
Arun Menon906de572013-06-18 17:01:40 -07008134 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8135 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308136 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008137 OMX_U32 frame_rate = 0;
8138 int consumed_len = 0;
8139 OMX_U32 num_MB_in_frame;
8140 OMX_U32 recovery_sei_flags = 1;
8141 int enable = 0;
8142 OMX_U32 mbaff = 0;
8143 int buf_index = p_buf_hdr - m_out_mem_ptr;
8144 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8145 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8146 p_buf_hdr->nOffset;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308147
Arun Menon906de572013-06-18 17:01:40 -07008148 if (!drv_ctx.extradata_info.uaddr) {
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308149 DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
Arun Menon906de572013-06-18 17:01:40 -07008150 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008151 }
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308152 if (!secure_mode)
8153 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Arun Menon906de572013-06-18 17:01:40 -07008154 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308155 else
8156 p_extra = m_other_extradata;
8157
Arun Menon906de572013-06-18 17:01:40 -07008158 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308159
8160 if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
Arun Menon906de572013-06-18 17:01:40 -07008161 p_extra = NULL;
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308162 return;
8163 }
Arun Menon906de572013-06-18 17:01:40 -07008164 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
8165 if (data) {
8166 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8167 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Surajit Podderd2644d52013-08-28 17:59:06 +05308168 if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
Arun Menon906de572013-06-18 17:01:40 -07008169 DEBUG_PRINT_LOW("Invalid extra data size");
8170 break;
8171 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308172 DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
Arun Menon906de572013-06-18 17:01:40 -07008173 switch ((unsigned long)data->eType) {
8174 case EXTRADATA_INTERLACE_VIDEO:
8175 struct msm_vidc_interlace_payload *payload;
8176 payload = (struct msm_vidc_interlace_payload *)data->data;
8177 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8178 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8179 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008180 else if (payload && (payload->format == INTERLACE_FRAME_TOPFIELDFIRST ||
8181 payload->format == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8182 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8183 enable = 1;
8184 } else {
Arun Menon906de572013-06-18 17:01:40 -07008185 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8186 enable = 1;
8187 }
8188 if (m_enable_android_native_buffers)
8189 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8190 PP_PARAM_INTERLACED, (void*)&enable);
Pushkaraj Patil0ddb2e02013-11-12 11:53:58 +05308191 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008192 append_interlace_extradata(p_extra, payload->format);
8193 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8194 }
8195 break;
8196 case EXTRADATA_FRAME_RATE:
8197 struct msm_vidc_framerate_payload *frame_rate_payload;
8198 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8199 frame_rate = frame_rate_payload->frame_rate;
8200 break;
8201 case EXTRADATA_TIMESTAMP:
8202 struct msm_vidc_ts_payload *time_stamp_payload;
8203 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308204 time_stamp = time_stamp_payload->timestamp_lo;
8205 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8206 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008207 break;
8208 case EXTRADATA_NUM_CONCEALED_MB:
8209 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8210 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8211 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8212 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8213 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8214 break;
8215 case EXTRADATA_INDEX:
8216 int *etype;
8217 etype = (int *)(data->data);
8218 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8219 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8220 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8221 if (aspect_ratio_payload) {
8222 ((struct vdec_output_frameinfo *)
8223 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8224 ((struct vdec_output_frameinfo *)
8225 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8226 }
8227 }
8228 break;
8229 case EXTRADATA_RECOVERY_POINT_SEI:
8230 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8231 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8232 recovery_sei_flags = recovery_sei_payload->flags;
8233 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8234 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008235 DEBUG_PRINT_HIGH("");
8236 DEBUG_PRINT_HIGH("***************************************************");
8237 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
8238 DEBUG_PRINT_HIGH("***************************************************");
Arun Menon906de572013-06-18 17:01:40 -07008239 }
8240 break;
8241 case EXTRADATA_PANSCAN_WINDOW:
8242 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8243 break;
8244 case EXTRADATA_MPEG2_SEQDISP:
8245 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8246 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8247 if (seqdisp_payload) {
8248 m_disp_hor_size = seqdisp_payload->disp_width;
8249 m_disp_vert_size = seqdisp_payload->disp_height;
8250 }
8251 break;
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308252 case EXTRADATA_S3D_FRAME_PACKING:
8253 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
8254 s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)data->data;
8255 if (!secure_mode && (client_extradata & OMX_FRAMEPACK_EXTRADATA)) {
8256 append_framepack_extradata(p_extra, s3d_frame_packing_payload);
8257 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8258 }
8259 break;
Arun Menon906de572013-06-18 17:01:40 -07008260 default:
8261 goto unrecognized_extradata;
8262 }
8263 consumed_len += data->nSize;
8264 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8265 }
8266 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8267 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8268 append_frame_info_extradata(p_extra,
8269 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308270 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008271 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008272 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008273 }
8274 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008275unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07008276 if (!secure_mode && client_extradata)
8277 append_terminator_extradata(p_extra);
8278 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008279}
8280
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008281OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008282 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008283{
Arun Menon906de572013-06-18 17:01:40 -07008284 OMX_ERRORTYPE ret = OMX_ErrorNone;
8285 struct v4l2_control control;
8286 if (m_state != OMX_StateLoaded) {
8287 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8288 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008289 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008290 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
Arun Menon906de572013-06-18 17:01:40 -07008291 client_extradata, requested_extradata, enable, is_internal);
8292
8293 if (!is_internal) {
8294 if (enable)
8295 client_extradata |= requested_extradata;
8296 else
8297 client_extradata = client_extradata & ~requested_extradata;
8298 }
8299
8300 if (enable) {
8301 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8302 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8303 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8304 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8305 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008306 " Quality of interlaced clips might be impacted.");
Arun Menon906de572013-06-18 17:01:40 -07008307 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308308 }
8309 if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008310 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8311 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8312 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008313 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
Arun Menon906de572013-06-18 17:01:40 -07008314 }
8315 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8316 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8317 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008318 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
Arun Menon906de572013-06-18 17:01:40 -07008319 }
8320 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8321 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8322 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008323 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
Arun Menon906de572013-06-18 17:01:40 -07008324 }
8325 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8326 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8327 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008328 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008329 }
8330 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8331 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8332 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008333 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008334 }
8335 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8336 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8337 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8338 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008339 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
Arun Menon906de572013-06-18 17:01:40 -07008340 }
8341 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308342 }
8343 if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
Arun Menon906de572013-06-18 17:01:40 -07008344 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8345 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8346 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008347 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
Arun Menon906de572013-06-18 17:01:40 -07008348 }
8349 }
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308350 if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
8351 if (output_capability == V4L2_PIX_FMT_H264) {
8352 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
8353 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8354 control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
8355 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8356 DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
8357 }
8358 } else {
8359 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
8360 }
8361 }
Arun Menon906de572013-06-18 17:01:40 -07008362 }
8363 ret = get_buffer_req(&drv_ctx.op_buf);
8364 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008365}
8366
8367OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8368{
Arun Menon906de572013-06-18 17:01:40 -07008369 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8370 OMX_U8 *data_ptr = extra->data, data = 0;
8371 while (byte_count < extra->nDataSize) {
8372 data = *data_ptr;
8373 while (data) {
8374 num_MB += (data&0x01);
8375 data >>= 1;
8376 }
8377 data_ptr++;
8378 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008379 }
Arun Menon906de572013-06-18 17:01:40 -07008380 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8381 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8382 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008383}
8384
8385void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8386{
Arun Menon906de572013-06-18 17:01:40 -07008387 if (!m_debug_extradata)
8388 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008389
8390 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008391 "============== Extra Data =============="
8392 " Size: %lu"
8393 " Version: %lu"
8394 " PortIndex: %lu"
8395 " Type: %x"
8396 " DataSize: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008397 extra->nSize, extra->nVersion.nVersion,
8398 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008399
Arun Menon906de572013-06-18 17:01:40 -07008400 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8401 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8402 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008403 "------ Interlace Format ------"
8404 " Size: %lu"
8405 " Version: %lu"
8406 " PortIndex: %lu"
8407 " Is Interlace Format: %d"
8408 " Interlace Formats: %lu"
8409 "=========== End of Interlace ===========",
Arun Menon906de572013-06-18 17:01:40 -07008410 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8411 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8412 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8413 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8414
8415 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008416 "-------- Frame Format --------"
8417 " Picture Type: %d"
8418 " Interlace Type: %d"
8419 " Pan Scan Total Frame Num: %lu"
8420 " Concealed Macro Blocks: %lu"
8421 " frame rate: %lu"
8422 " Time Stamp: %llu"
8423 " Aspect Ratio X: %lu"
8424 " Aspect Ratio Y: %lu",
Arun Menon906de572013-06-18 17:01:40 -07008425 fminfo->ePicType,
8426 fminfo->interlaceType,
8427 fminfo->panScan.numWindows,
8428 fminfo->nConcealedMacroblocks,
8429 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308430 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008431 fminfo->aspectRatio.aspectRatioX,
8432 fminfo->aspectRatio.aspectRatioY);
8433
8434 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8435 DEBUG_PRINT_HIGH(
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008436 "------------------------------"
8437 " Pan Scan Frame Num: %lu"
8438 " Rectangle x: %ld"
8439 " Rectangle y: %ld"
8440 " Rectangle dx: %ld"
8441 " Rectangle dy: %ld",
Arun Menon906de572013-06-18 17:01:40 -07008442 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8443 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8444 }
8445
8446 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308447 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
8448 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8449 DEBUG_PRINT_HIGH(
8450 "------------------ Framepack Format ----------\n"
8451 " id: %lu \n"
8452 " cancel_flag: %lu \n"
8453 " type: %lu \n"
8454 " quincunx_sampling_flagFormat: %lu \n"
8455 " content_interpretation_type: %lu \n"
8456 " content_interpretation_type: %lu \n"
8457 " spatial_flipping_flag: %lu \n"
8458 " frame0_flipped_flag: %lu \n"
8459 " field_views_flag: %lu \n"
8460 " current_frame_is_frame0_flag: %lu \n"
8461 " frame0_self_contained_flag: %lu \n"
8462 " frame1_self_contained_flag: %lu \n"
8463 " frame0_grid_position_x: %lu \n"
8464 " frame0_grid_position_y: %lu \n"
8465 " frame1_grid_position_x: %lu \n"
8466 " frame1_grid_position_y: %lu \n"
8467 " reserved_byte: %lu \n"
8468 " repetition_period: %lu \n"
8469 " extension_flag: %lu \n"
8470 "================== End of Framepack ===========",
8471 framepack->id,
8472 framepack->cancel_flag,
8473 framepack->type,
8474 framepack->quincunx_sampling_flag,
8475 framepack->content_interpretation_type,
8476 framepack->spatial_flipping_flag,
8477 framepack->frame0_flipped_flag,
8478 framepack->field_views_flag,
8479 framepack->current_frame_is_frame0_flag,
8480 framepack->frame0_self_contained_flag,
8481 framepack->frame1_self_contained_flag,
8482 framepack->frame0_grid_position_x,
8483 framepack->frame0_grid_position_y,
8484 framepack->frame1_grid_position_x,
8485 framepack->frame1_grid_position_y,
8486 framepack->reserved_byte,
8487 framepack->repetition_period,
8488 framepack->extension_flag);
Arun Menon906de572013-06-18 17:01:40 -07008489 } else if (extra->eType == OMX_ExtraDataNone) {
8490 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8491 } else {
8492 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008493 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008494}
8495
8496void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008497 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008498{
Arun Menon906de572013-06-18 17:01:40 -07008499 OMX_STREAMINTERLACEFORMAT *interlace_format;
8500 OMX_U32 mbaff = 0;
8501 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8502 return;
8503 }
8504 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8505 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8506 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8507 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8508 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8509 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8510 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8511 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8512 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8513 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8514 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8515 interlace_format->bInterlaceFormat = OMX_FALSE;
8516 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8517 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008518 } else if ((interlaced_format_type == INTERLACE_FRAME_TOPFIELDFIRST) && !mbaff) {
8519 interlace_format->bInterlaceFormat = OMX_TRUE;
8520 interlace_format->nInterlaceFormats = OMX_InterlaceFrameTopFieldFirst;
8521 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8522 } else if ((interlaced_format_type == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8523 interlace_format->bInterlaceFormat = OMX_TRUE;
8524 interlace_format->nInterlaceFormats = OMX_InterlaceFrameBottomFieldFirst;
8525 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07008526 } else {
8527 interlace_format->bInterlaceFormat = OMX_TRUE;
8528 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8529 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8530 }
8531 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008532}
8533
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008534void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008535 struct vdec_aspectratioinfo *aspect_ratio_info,
8536 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008537{
Arun Menon906de572013-06-18 17:01:40 -07008538 m_extradata = frame_info;
8539 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8540 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308541 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008542 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008543}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008544
8545void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008546 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308547 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008548 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008549{
Arun Menon906de572013-06-18 17:01:40 -07008550 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8551 struct msm_vidc_panscan_window *panscan_window;
8552 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008553 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008554 }
Arun Menon906de572013-06-18 17:01:40 -07008555 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8556 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8557 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8558 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8559 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8560 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8561 switch (picture_type) {
8562 case PICTURE_TYPE_I:
8563 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8564 break;
8565 case PICTURE_TYPE_P:
8566 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8567 break;
8568 case PICTURE_TYPE_B:
8569 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8570 break;
8571 default:
8572 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8573 }
8574 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8575 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8576 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8577 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8578 else
8579 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8580 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8581 frame_info->nConcealedMacroblocks = num_conceal_mb;
8582 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308583 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008584 frame_info->panScan.numWindows = 0;
8585 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8586 if (m_disp_hor_size && m_disp_vert_size) {
8587 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8588 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8589 }
8590 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008591
Arun Menon906de572013-06-18 17:01:40 -07008592 if (panscan_payload) {
8593 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8594 panscan_window = &panscan_payload->wnd[0];
8595 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8596 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8597 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8598 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8599 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8600 panscan_window++;
8601 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008602 }
Arun Menon906de572013-06-18 17:01:40 -07008603 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8604 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008605}
8606
8607void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8608{
Arun Menon906de572013-06-18 17:01:40 -07008609 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8610 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8611 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8612 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8613 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8614 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8615 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8616 *portDefn = m_port_def;
8617 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008618 "stride = %lu sliceheight = %lu",portDefn->format.video.nFrameHeight,
Arun Menon906de572013-06-18 17:01:40 -07008619 portDefn->format.video.nFrameWidth,
8620 portDefn->format.video.nStride,
8621 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008622}
8623
Maheshwar Ajjad2df2182013-10-24 19:20:34 +05308624void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8625 struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
8626{
8627 OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
8628 if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
8629 DEBUG_PRINT_ERROR("frame packing size mismatch");
8630 return;
8631 }
8632 extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
8633 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8634 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8635 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
8636 extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8637 framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)extra->data;
8638 framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
8639 framepack->nVersion.nVersion = OMX_SPEC_VERSION;
8640 framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8641 memcpy(&framepack->id, s3d_frame_packing_payload,
8642 sizeof(struct msm_vidc_s3d_frame_packing_payload));
8643 memcpy(&m_frame_pack_arrangement, framepack,
8644 sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
8645 print_debug_extradata(extra);
8646}
8647
Shalaj Jain273b3e02012-06-22 19:08:03 -07008648void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8649{
Arun Menon906de572013-06-18 17:01:40 -07008650 if (!client_extradata) {
8651 return;
8652 }
8653 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8654 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8655 extra->eType = OMX_ExtraDataNone;
8656 extra->nDataSize = 0;
8657 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008658
Arun Menon906de572013-06-18 17:01:40 -07008659 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008660}
8661
8662OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8663{
Arun Menon906de572013-06-18 17:01:40 -07008664 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8665 if (index >= drv_ctx.ip_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008666 DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
Arun Menon906de572013-06-18 17:01:40 -07008667 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008668 }
Arun Menon906de572013-06-18 17:01:40 -07008669 if (m_desc_buffer_ptr == NULL) {
8670 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8671 calloc( (sizeof(desc_buffer_hdr)),
8672 drv_ctx.ip_buf.actualcount);
8673 if (m_desc_buffer_ptr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008674 DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008675 return OMX_ErrorInsufficientResources;
8676 }
8677 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008678
Arun Menon906de572013-06-18 17:01:40 -07008679 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8680 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008681 DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
Arun Menon906de572013-06-18 17:01:40 -07008682 return OMX_ErrorInsufficientResources;
8683 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008684
Arun Menon906de572013-06-18 17:01:40 -07008685 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008686}
8687
8688void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8689{
Arun Menon906de572013-06-18 17:01:40 -07008690 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8691 if (m_demux_entries < 8192) {
8692 m_demux_offsets[m_demux_entries++] = address_offset;
8693 }
8694 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008695}
8696
8697void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8698{
Arun Menon906de572013-06-18 17:01:40 -07008699 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8700 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8701 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008702
Arun Menon906de572013-06-18 17:01:40 -07008703 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008704
Arun Menon906de572013-06-18 17:01:40 -07008705 while (index < bytes_to_parse) {
8706 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8707 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8708 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8709 (buf[index+2] == 0x01)) ) {
8710 //Found start code, insert address offset
8711 insert_demux_addr_offset(index);
8712 if (buf[index+2] == 0x01) // 3 byte start code
8713 index += 3;
8714 else //4 byte start code
8715 index += 4;
8716 } else
8717 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008718 }
Arun Menon906de572013-06-18 17:01:40 -07008719 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8720 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008721}
8722
8723OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8724{
Arun Menon906de572013-06-18 17:01:40 -07008725 //fix this, handle 3 byte start code, vc1 terminator entry
8726 OMX_U8 *p_demux_data = NULL;
8727 OMX_U32 desc_data = 0;
8728 OMX_U32 start_addr = 0;
8729 OMX_U32 nal_size = 0;
8730 OMX_U32 suffix_byte = 0;
8731 OMX_U32 demux_index = 0;
8732 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008733
Arun Menon906de572013-06-18 17:01:40 -07008734 if (m_desc_buffer_ptr == NULL) {
8735 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8736 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008737 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008738
Arun Menon906de572013-06-18 17:01:40 -07008739 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8740 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8741 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8742 return OMX_ErrorBadParameter;
8743 }
8744
8745 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8746
8747 if ( ((OMX_U8*)p_demux_data == NULL) ||
8748 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8749 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8750 return OMX_ErrorBadParameter;
8751 } else {
8752 for (; demux_index < m_demux_entries; demux_index++) {
8753 desc_data = 0;
8754 start_addr = m_demux_offsets[demux_index];
8755 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8756 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8757 } else {
8758 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8759 }
8760 if (demux_index < (m_demux_entries - 1)) {
8761 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8762 } else {
8763 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8764 }
8765 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8766 (void *)start_addr,
8767 suffix_byte,
8768 nal_size,
8769 demux_index);
8770 desc_data = (start_addr >> 3) << 1;
8771 desc_data |= (start_addr & 7) << 21;
8772 desc_data |= suffix_byte << 24;
8773
8774 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8775 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8776 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8777 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8778
8779 p_demux_data += 16;
8780 }
8781 if (codec_type_parse == CODEC_TYPE_VC1) {
8782 DEBUG_PRINT_LOW("VC1 terminator entry");
8783 desc_data = 0;
8784 desc_data = 0x82 << 24;
8785 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8786 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8787 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8788 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8789 p_demux_data += 16;
8790 m_demux_entries++;
8791 }
8792 //Add zero word to indicate end of descriptors
8793 memset(p_demux_data, 0, sizeof(OMX_U32));
8794
8795 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8796 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8797 }
8798 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8799 m_demux_entries = 0;
8800 DEBUG_PRINT_LOW("Demux table complete!");
8801 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008802}
8803
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008804OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008805{
Arun Menon906de572013-06-18 17:01:40 -07008806 OMX_ERRORTYPE err = OMX_ErrorNone;
8807 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8808 if (iDivXDrmDecrypt) {
8809 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8810 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008811 DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008812 delete iDivXDrmDecrypt;
8813 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008814 }
8815 } else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008816 DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
Arun Menon906de572013-06-18 17:01:40 -07008817 err = OMX_ErrorUndefined;
8818 }
8819 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008820}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008821
Vinay Kaliada4f4422013-01-09 10:45:03 -08008822omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8823{
Arun Menon906de572013-06-18 17:01:40 -07008824 enabled = false;
8825 omx = NULL;
8826 init_members();
8827 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008828}
8829
8830void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8831{
Arun Menon906de572013-06-18 17:01:40 -07008832 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008833}
8834
Arun Menon906de572013-06-18 17:01:40 -07008835void omx_vdec::allocate_color_convert_buf::init_members()
8836{
8837 allocated_count = 0;
8838 buffer_size_req = 0;
8839 buffer_alignment_req = 0;
8840 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8841 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8842 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8843 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008844#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008845 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008846#endif
Arun Menon906de572013-06-18 17:01:40 -07008847 for (int i = 0; i < MAX_COUNT; i++)
8848 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008849}
8850
Arun Menon906de572013-06-18 17:01:40 -07008851omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8852{
8853 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008854}
8855
8856bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8857{
Arun Menon906de572013-06-18 17:01:40 -07008858 bool status = true;
8859 unsigned int src_size = 0, destination_size = 0;
8860 OMX_COLOR_FORMATTYPE drv_color_format;
8861 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008862 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07008863 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008864 }
Arun Menon906de572013-06-18 17:01:40 -07008865 if (!enabled) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008866 DEBUG_PRINT_HIGH("No color conversion required");
Arun Menon906de572013-06-18 17:01:40 -07008867 return status;
8868 }
8869 pthread_mutex_lock(&omx->c_lock);
8870 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8871 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008872 DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
Arun Menon906de572013-06-18 17:01:40 -07008873 status = false;
8874 goto fail_update_buf_req;
8875 }
8876 c2d.close();
8877 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8878 omx->drv_ctx.video_resolution.frame_width,
8879 NV12_128m,YCbCr420P);
8880 if (status) {
8881 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8882 if (status)
8883 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8884 }
8885 if (status) {
8886 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8887 !destination_size) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008888 DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
Arun Menon906de572013-06-18 17:01:40 -07008889 "driver size %d destination size %d",
8890 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8891 status = false;
8892 c2d.close();
8893 buffer_size_req = 0;
8894 } else {
8895 buffer_size_req = destination_size;
8896 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8897 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8898 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8899 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8900 }
8901 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008902fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008903 pthread_mutex_unlock(&omx->c_lock);
8904 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008905}
8906
8907bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008908 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008909{
Arun Menon906de572013-06-18 17:01:40 -07008910 bool status = true;
8911 OMX_COLOR_FORMATTYPE drv_color_format;
8912 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008913 DEBUG_PRINT_ERROR("Invalid client in color convert");
Arun Menon906de572013-06-18 17:01:40 -07008914 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008915 }
Arun Menon906de572013-06-18 17:01:40 -07008916 pthread_mutex_lock(&omx->c_lock);
8917 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8918 drv_color_format = (OMX_COLOR_FORMATTYPE)
8919 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8920 else {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008921 DEBUG_PRINT_ERROR("Incorrect color format");
Arun Menon906de572013-06-18 17:01:40 -07008922 status = false;
8923 }
8924 if (status && (drv_color_format != dest_color_format)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008925 DEBUG_PRINT_LOW("Enabling C2D");
Arun Menon906de572013-06-18 17:01:40 -07008926 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008927 DEBUG_PRINT_ERROR("Unsupported color format for c2d");
Arun Menon906de572013-06-18 17:01:40 -07008928 status = false;
8929 } else {
8930 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8931 if (enabled)
8932 c2d.destroy();
8933 enabled = false;
8934 if (!c2d.init()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008935 DEBUG_PRINT_ERROR("open failed for c2d");
Arun Menon906de572013-06-18 17:01:40 -07008936 status = false;
8937 } else
8938 enabled = true;
8939 }
8940 } else {
8941 if (enabled)
8942 c2d.destroy();
8943 enabled = false;
8944 }
8945 pthread_mutex_unlock(&omx->c_lock);
8946 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008947}
8948
8949OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8950{
Arun Menon906de572013-06-18 17:01:40 -07008951 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008952 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07008953 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008954 }
Arun Menon906de572013-06-18 17:01:40 -07008955 if (!enabled)
8956 return omx->m_out_mem_ptr;
8957 return m_out_mem_ptr_client;
8958}
8959
8960 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
8961(OMX_BUFFERHEADERTYPE *bufadd)
8962{
8963 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008964 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07008965 return NULL;
8966 }
8967 if (!enabled)
8968 return bufadd;
8969
8970 unsigned index = 0;
8971 index = bufadd - omx->m_out_mem_ptr;
8972 if (index < omx->drv_ctx.op_buf.actualcount) {
8973 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
8974 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
8975 bool status;
8976 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
8977 pthread_mutex_lock(&omx->c_lock);
8978 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
8979 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
8980 pmem_baseaddress[index], pmem_baseaddress[index]);
8981 pthread_mutex_unlock(&omx->c_lock);
8982 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
8983 if (!status) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008984 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
Arun Menon906de572013-06-18 17:01:40 -07008985 m_out_mem_ptr_client[index].nFilledLen = 0;
8986 return &m_out_mem_ptr_client[index];
8987 }
8988 } else
8989 m_out_mem_ptr_client[index].nFilledLen = 0;
8990 return &m_out_mem_ptr_client[index];
8991 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07008992 DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07008993 return NULL;
8994}
8995
8996 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
8997(OMX_BUFFERHEADERTYPE *bufadd)
8998{
8999 if (!omx) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009000 DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009001 return NULL;
9002 }
9003 if (!enabled)
9004 return bufadd;
9005 unsigned index = 0;
9006 index = bufadd - m_out_mem_ptr_client;
9007 if (index < omx->drv_ctx.op_buf.actualcount) {
9008 return &omx->m_out_mem_ptr[index];
9009 }
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009010 DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
Arun Menon906de572013-06-18 17:01:40 -07009011 return NULL;
9012}
9013 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9014(unsigned int &buffer_size)
9015{
9016 bool status = true;
9017 pthread_mutex_lock(&omx->c_lock);
9018 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009019 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07009020 else {
9021 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009022 DEBUG_PRINT_ERROR("Get buffer size failed");
Arun Menon906de572013-06-18 17:01:40 -07009023 status = false;
9024 goto fail_get_buffer_size;
9025 }
9026 }
9027 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9028 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9029 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9030 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009031fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07009032 pthread_mutex_unlock(&omx->c_lock);
9033 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009034}
9035OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07009036 OMX_BUFFERHEADERTYPE *bufhdr)
9037{
9038 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009039
Arun Menon906de572013-06-18 17:01:40 -07009040 if (!enabled)
9041 return omx->free_output_buffer(bufhdr);
9042 if (enabled && omx->is_component_secure())
9043 return OMX_ErrorNone;
9044 if (!allocated_count || !bufhdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009045 DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
Arun Menon906de572013-06-18 17:01:40 -07009046 return OMX_ErrorBadParameter;
9047 }
9048 index = bufhdr - m_out_mem_ptr_client;
9049 if (index >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009050 DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
Arun Menon906de572013-06-18 17:01:40 -07009051 return OMX_ErrorBadParameter;
9052 }
9053 if (pmem_fd[index] > 0) {
9054 munmap(pmem_baseaddress[index], buffer_size_req);
9055 close(pmem_fd[index]);
9056 }
9057 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009058#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009059 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009060#endif
Arun Menon906de572013-06-18 17:01:40 -07009061 m_heap_ptr[index].video_heap_ptr = NULL;
9062 if (allocated_count > 0)
9063 allocated_count--;
9064 else
9065 allocated_count = 0;
9066 if (!allocated_count) {
9067 pthread_mutex_lock(&omx->c_lock);
9068 c2d.close();
9069 init_members();
9070 pthread_mutex_unlock(&omx->c_lock);
9071 }
9072 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009073}
9074
9075OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07009076 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08009077{
Arun Menon906de572013-06-18 17:01:40 -07009078 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9079 if (!enabled) {
9080 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9081 return eRet;
9082 }
9083 if (enabled && omx->is_component_secure()) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009084 DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
Arun Menon906de572013-06-18 17:01:40 -07009085 omx->is_component_secure());
9086 return OMX_ErrorUnsupportedSetting;
9087 }
9088 if (!bufferHdr || bytes > buffer_size_req) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009089 DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
9090 DEBUG_PRINT_ERROR("color_convert buffer_size_req %d bytes %lu",
Arun Menon906de572013-06-18 17:01:40 -07009091 buffer_size_req,bytes);
9092 return OMX_ErrorBadParameter;
9093 }
9094 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009095 DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009096 return OMX_ErrorInsufficientResources;
9097 }
9098 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9099 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9100 port,appData,omx->drv_ctx.op_buf.buffer_size);
9101 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009102 DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009103 return eRet;
9104 }
9105 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
Surajit Podderd2644d52013-08-28 17:59:06 +05309106 (int)omx->drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009107 DEBUG_PRINT_ERROR("Invalid header index %d",
Arun Menon906de572013-06-18 17:01:40 -07009108 (temp_bufferHdr - omx->m_out_mem_ptr));
9109 return OMX_ErrorUndefined;
9110 }
9111 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009112#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07009113 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9114 buffer_size_req,buffer_alignment_req,
9115 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9116 0);
9117 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9118 if (op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009119 DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
Arun Menon906de572013-06-18 17:01:40 -07009120 return OMX_ErrorInsufficientResources;
9121 }
9122 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9123 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009124
Arun Menon906de572013-06-18 17:01:40 -07009125 if (pmem_baseaddress[i] == MAP_FAILED) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009126 DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
Arun Menon906de572013-06-18 17:01:40 -07009127 close(pmem_fd[i]);
9128 omx->free_ion_memory(&op_buf_ion_info[i]);
9129 return OMX_ErrorInsufficientResources;
9130 }
9131 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9132 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9133 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009134#endif
Arun Menon906de572013-06-18 17:01:40 -07009135 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9136 m_pmem_info_client[i].offset = 0;
9137 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9138 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9139 m_platform_list_client[i].nEntries = 1;
9140 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9141 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9142 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9143 m_out_mem_ptr_client[i].nFilledLen = 0;
9144 m_out_mem_ptr_client[i].nFlags = 0;
9145 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9146 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9147 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9148 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9149 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9150 m_out_mem_ptr_client[i].pAppPrivate = appData;
9151 *bufferHdr = &m_out_mem_ptr_client[i];
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009152 DEBUG_PRINT_ERROR("IL client buffer header %p", *bufferHdr);
Arun Menon906de572013-06-18 17:01:40 -07009153 allocated_count++;
9154 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009155}
9156
9157bool omx_vdec::is_component_secure()
9158{
Arun Menon906de572013-06-18 17:01:40 -07009159 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009160}
9161
9162bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9163{
Arun Menon906de572013-06-18 17:01:40 -07009164 bool status = true;
9165 if (!enabled) {
9166 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9167 dest_color_format = (OMX_COLOR_FORMATTYPE)
9168 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9169 else
9170 status = false;
9171 } else {
9172 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9173 status = false;
9174 } else
9175 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9176 }
9177 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009178}
Arun Menonbdb80b02013-08-12 17:45:54 -07009179
Arun Menonbdb80b02013-08-12 17:45:54 -07009180void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
9181{
9182 int i = 0;
9183 bool buf_present = false;
9184 pthread_mutex_lock(&m_lock);
9185 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9186 //check the buffer fd, offset, uv addr with list contents
9187 //If present increment reference.
9188 if ((out_dynamic_list[i].fd == fd) &&
9189 (out_dynamic_list[i].offset == offset)) {
9190 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009191 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009192 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9193 buf_present = true;
9194 break;
9195 }
9196 }
9197 if (!buf_present) {
9198 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9199 //search for a entry to insert details of the new buffer
9200 if (out_dynamic_list[i].dup_fd == 0) {
9201 out_dynamic_list[i].fd = fd;
9202 out_dynamic_list[i].offset = offset;
9203 out_dynamic_list[i].dup_fd = dup(fd);
9204 out_dynamic_list[i].ref_count++;
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009205 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009206 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9207 break;
9208 }
9209 }
9210 }
9211 pthread_mutex_unlock(&m_lock);
9212}
9213
9214void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9215{
9216 int i = 0;
9217 pthread_mutex_lock(&m_lock);
9218 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9219 //check the buffer fd, offset, uv addr with list contents
9220 //If present decrement reference.
9221 if ((out_dynamic_list[i].fd == fd) &&
9222 (out_dynamic_list[i].offset == offset)) {
9223 out_dynamic_list[i].ref_count--;
9224 if (out_dynamic_list[i].ref_count == 0) {
9225 close(out_dynamic_list[i].dup_fd);
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009226 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d",
Arun Menonbdb80b02013-08-12 17:45:54 -07009227 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9228 out_dynamic_list[i].dup_fd = 0;
9229 out_dynamic_list[i].fd = 0;
9230 out_dynamic_list[i].offset = 0;
9231 }
9232 break;
9233 }
9234 }
9235 if (i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian43918e22013-10-21 20:04:23 -07009236 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
Arun Menonbdb80b02013-08-12 17:45:54 -07009237 }
9238 pthread_mutex_unlock(&m_lock);
9239}
Leena Winterrowd974fd1f2013-10-30 10:58:02 -07009240
9241#ifdef _MSM8974_
9242void omx_vdec::send_codec_config() {
9243 if (codec_config_flag) {
9244 unsigned p1 = 0; // Parameter - 1
9245 unsigned p2 = 0; // Parameter - 2
9246 unsigned ident = 0;
9247 pthread_mutex_lock(&m_lock);
9248 DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
9249 while (m_etb_q.m_size) {
9250 m_etb_q.pop_entry(&p1,&p2,&ident);
9251 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
9252 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9253 if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
9254 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9255 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
9256 omx_report_error();
9257 }
9258 } else {
9259 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
9260 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
9261 }
9262 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
9263 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9264 if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
9265 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
9266 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
9267 omx_report_error ();
9268 }
9269 } else {
9270 pending_input_buffers++;
9271 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
9272 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
9273 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
9274 }
9275 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
9276 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
9277 (OMX_BUFFERHEADERTYPE *)p1);
9278 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
9279 }
9280 }
9281 pthread_mutex_unlock(&m_lock);
9282 }
9283}
9284#endif