blob: b3844673a3844a4f74127dcc657bb08976a2126c [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#ifdef META_DATA_MODE_SUPPORTED
53#include <media/hardware/HardwareAPI.h>
54#endif
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080055#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070056
57#ifndef _ANDROID_
58#include <sys/ioctl.h>
59#include <sys/mman.h>
60#endif //_ANDROID_
61
62#ifdef _ANDROID_
63#include <cutils/properties.h>
64#undef USE_EGL_IMAGE_GPU
65#endif
66
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070067#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070068
69#ifdef _ANDROID_
70#include "DivXDrmDecrypt.h"
71#endif //_ANDROID_
72
Arun Menon9af783f2013-10-22 12:57:14 -070073#ifdef META_DATA_MODE_SUPPORTED
74#include "QComOMXMetadata.h"
75#endif
76
Shalaj Jain273b3e02012-06-22 19:08:03 -070077#ifdef USE_EGL_IMAGE_GPU
78#include <EGL/egl.h>
79#include <EGL/eglQCOM.h>
80#define EGL_BUFFER_HANDLE_QCOM 0x4F00
81#define EGL_BUFFER_OFFSET_QCOM 0x4F01
82#endif
Vinay Kalia21649b32013-03-18 17:28:07 -070083
Jayasena Sangaraboina51230642013-08-21 18:02:13 -070084#define BUFFER_LOG_LOC "/data/misc/media"
85
Shalaj Jain273b3e02012-06-22 19:08:03 -070086#ifdef OUTPUT_EXTRADATA_LOG
87FILE *outputExtradataFile;
88char ouputextradatafilename [] = "/data/extradata";
89#endif
90
91#define DEFAULT_FPS 30
92#define MAX_INPUT_ERROR DEFAULT_FPS
93#define MAX_SUPPORTED_FPS 120
94
95#define VC1_SP_MP_START_CODE 0xC5000000
96#define VC1_SP_MP_START_CODE_MASK 0xFF000000
97#define VC1_AP_SEQ_START_CODE 0x0F010000
98#define VC1_STRUCT_C_PROFILE_MASK 0xF0
99#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
100#define VC1_SIMPLE_PROFILE 0
101#define VC1_MAIN_PROFILE 1
102#define VC1_ADVANCE_PROFILE 3
103#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
104#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
105#define VC1_STRUCT_C_LEN 4
106#define VC1_STRUCT_C_POS 8
107#define VC1_STRUCT_A_POS 12
108#define VC1_STRUCT_B_POS 24
109#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700110#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700111
112#define MEM_DEVICE "/dev/ion"
113#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
114
115#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700116extern "C" {
117#include<utils/Log.h>
118}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700119#endif//_ANDROID_
120
Vinay Kalia53fa6832012-10-11 17:55:30 -0700121#define SZ_4K 0x1000
122#define SZ_1M 0x100000
123
Shalaj Jain273b3e02012-06-22 19:08:03 -0700124#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
125#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 -0700126#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
127
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800128#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700129
130int debug_level = PRIO_ERROR;
131
Shalaj Jain273b3e02012-06-22 19:08:03 -0700132void* async_message_thread (void *input)
133{
Arun Menon906de572013-06-18 17:01:40 -0700134 OMX_BUFFERHEADERTYPE *buffer;
135 struct v4l2_plane plane[VIDEO_MAX_PLANES];
136 struct pollfd pfd;
137 struct v4l2_buffer v4l2_buf;
138 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
139 struct v4l2_event dqevent;
140 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
141 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
142 pfd.fd = omx->drv_ctx.video_driver_fd;
143 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
144 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
145 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
146 while (1) {
147 rc = poll(&pfd, 1, POLL_TIMEOUT);
148 if (!rc) {
149 DEBUG_PRINT_ERROR("Poll timedout\n");
150 break;
151 } else if (rc < 0) {
152 DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
153 break;
154 }
155 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
156 struct vdec_msginfo vdec_msg;
157 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
158 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
159 v4l2_buf.length = omx->drv_ctx.num_planes;
160 v4l2_buf.m.planes = plane;
161 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
162 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
163 vdec_msg.status_code=VDEC_S_SUCCESS;
164 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
165 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
166 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
167 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
168 (uint64_t)v4l2_buf.timestamp.tv_usec;
169 if (vdec_msg.msgdata.output_frame.len) {
170 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
171 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
172 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
173 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
174 }
175 if (omx->async_message_process(input,&vdec_msg) < 0) {
176 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
177 break;
178 }
179 }
180 }
181 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
182 struct vdec_msginfo vdec_msg;
183 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
184 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
185 v4l2_buf.length = 1;
186 v4l2_buf.m.planes = plane;
187 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
188 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
189 vdec_msg.status_code=VDEC_S_SUCCESS;
190 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
191 if (omx->async_message_process(input,&vdec_msg) < 0) {
192 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
193 break;
194 }
195 }
196 }
197 if (pfd.revents & POLLPRI) {
198 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
199 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
200 struct vdec_msginfo vdec_msg;
201 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
202 vdec_msg.status_code=VDEC_S_SUCCESS;
203 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved insufficient\n");
204 if (omx->async_message_process(input,&vdec_msg) < 0) {
205 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
206 break;
207 }
208 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
209 struct vdec_msginfo vdec_msg;
210 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
211 vdec_msg.status_code=VDEC_S_SUCCESS;
212 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved \n");
213 if (omx->async_message_process(input,&vdec_msg) < 0) {
214 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
215 break;
216 }
217 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
218 vdec_msg.status_code=VDEC_S_SUCCESS;
219 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved \n");
220 if (omx->async_message_process(input,&vdec_msg) < 0) {
221 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
222 break;
223 }
224 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
225 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
226 break;
227 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
228 struct vdec_msginfo vdec_msg;
229 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
230 vdec_msg.status_code=VDEC_S_SUCCESS;
231 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
232 if (omx->async_message_process(input,&vdec_msg) < 0) {
233 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
234 break;
235 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700236 }
237#ifdef META_DATA_MODE_SUPPORTED
238 else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
239 unsigned int *ptr = (unsigned int *)dqevent.u.data;
240 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d\n", ptr[0], ptr[1]);
241 omx->buf_ref_remove(ptr[0], ptr[1]);
242 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
243 unsigned int *ptr = (unsigned int *)dqevent.u.data;
244 struct vdec_msginfo vdec_msg;
245
246 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d\n", ptr[0], ptr[1]);
247
248 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
249 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
250 v4l2_buf.length = omx->drv_ctx.num_planes;
251 v4l2_buf.m.planes = plane;
252 v4l2_buf.index = ptr[5];
253 v4l2_buf.flags = 0;
254
255 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
256 vdec_msg.status_code = VDEC_S_SUCCESS;
257 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
258 vdec_msg.msgdata.output_frame.len = 0;
259 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
260 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
261 (uint64_t)ptr[4];
262 if (omx->async_message_process(input,&vdec_msg) < 0) {
263 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
264 break;
265 }
266 }
267#endif
268 else {
Arun Menon906de572013-06-18 17:01:40 -0700269 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
270 continue;
271 }
272 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700273 }
Arun Menon906de572013-06-18 17:01:40 -0700274 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
275 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700276}
277
278void* message_thread(void *input)
279{
Arun Menon906de572013-06-18 17:01:40 -0700280 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
281 unsigned char id;
282 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700283
Arun Menon906de572013-06-18 17:01:40 -0700284 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
285 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
286 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700287
Arun Menon906de572013-06-18 17:01:40 -0700288 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700289
Arun Menon906de572013-06-18 17:01:40 -0700290 if (0 == n) {
291 break;
292 }
293
294 if (1 == n) {
295 omx->process_event_cb(omx, id);
296 }
297 if ((n < 0) && (errno != EINTR)) {
298 DEBUG_PRINT_LOW("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
299 break;
300 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700301 }
Arun Menon906de572013-06-18 17:01:40 -0700302 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
303 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700304}
305
306void post_message(omx_vdec *omx, unsigned char id)
307{
Arun Menon906de572013-06-18 17:01:40 -0700308 int ret_value;
309 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
310 ret_value = write(omx->m_pipe_out, &id, 1);
311 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700312}
313
314// omx_cmd_queue destructor
315omx_vdec::omx_cmd_queue::~omx_cmd_queue()
316{
Arun Menon906de572013-06-18 17:01:40 -0700317 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700318}
319
320// omx cmd queue constructor
321omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
322{
323 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
324}
325
326// omx cmd queue insert
327bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
328{
Arun Menon906de572013-06-18 17:01:40 -0700329 bool ret = true;
330 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
331 m_q[m_write].id = id;
332 m_q[m_write].param1 = p1;
333 m_q[m_write].param2 = p2;
334 m_write++;
335 m_size ++;
336 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
337 m_write = 0;
338 }
339 } else {
340 ret = false;
341 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700342 }
Arun Menon906de572013-06-18 17:01:40 -0700343 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700344}
345
346// omx cmd queue pop
347bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
348{
Arun Menon906de572013-06-18 17:01:40 -0700349 bool ret = true;
350 if (m_size > 0) {
351 *id = m_q[m_read].id;
352 *p1 = m_q[m_read].param1;
353 *p2 = m_q[m_read].param2;
354 // Move the read pointer ahead
355 ++m_read;
356 --m_size;
357 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
358 m_read = 0;
359 }
360 } else {
361 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700362 }
Arun Menon906de572013-06-18 17:01:40 -0700363 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700364}
365
366// Retrieve the first mesg type in the queue
367unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
368{
369 return m_q[m_read].id;
370}
371
372#ifdef _ANDROID_
373omx_vdec::ts_arr_list::ts_arr_list()
374{
Arun Menon906de572013-06-18 17:01:40 -0700375 //initialize timestamps array
376 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700377}
378omx_vdec::ts_arr_list::~ts_arr_list()
379{
Arun Menon906de572013-06-18 17:01:40 -0700380 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700381}
382
383bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
384{
Arun Menon906de572013-06-18 17:01:40 -0700385 bool ret = true;
386 bool duplicate_ts = false;
387 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700388
Arun Menon906de572013-06-18 17:01:40 -0700389 //insert at the first available empty location
390 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
391 if (!m_ts_arr_list[idx].valid) {
392 //found invalid or empty entry, save timestamp
393 m_ts_arr_list[idx].valid = true;
394 m_ts_arr_list[idx].timestamp = ts;
395 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
396 ts, idx);
397 break;
398 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700399 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700400
Arun Menon906de572013-06-18 17:01:40 -0700401 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
402 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
403 ret = false;
404 }
405 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700406}
407
408bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
409{
Arun Menon906de572013-06-18 17:01:40 -0700410 bool ret = true;
411 int min_idx = -1;
412 OMX_TICKS min_ts = 0;
413 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700414
Arun Menon906de572013-06-18 17:01:40 -0700415 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700416
Arun Menon906de572013-06-18 17:01:40 -0700417 if (m_ts_arr_list[idx].valid) {
418 //found valid entry, save index
419 if (min_idx < 0) {
420 //first valid entry
421 min_ts = m_ts_arr_list[idx].timestamp;
422 min_idx = idx;
423 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
424 min_ts = m_ts_arr_list[idx].timestamp;
425 min_idx = idx;
426 }
427 }
428
Shalaj Jain273b3e02012-06-22 19:08:03 -0700429 }
430
Arun Menon906de572013-06-18 17:01:40 -0700431 if (min_idx < 0) {
432 //no valid entries found
433 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
434 ts = 0;
435 ret = false;
436 } else {
437 ts = m_ts_arr_list[min_idx].timestamp;
438 m_ts_arr_list[min_idx].valid = false;
439 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
440 ts, min_idx);
441 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700442
Arun Menon906de572013-06-18 17:01:40 -0700443 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700444
445}
446
447
448bool omx_vdec::ts_arr_list::reset_ts_list()
449{
Arun Menon906de572013-06-18 17:01:40 -0700450 bool ret = true;
451 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700452
Arun Menon906de572013-06-18 17:01:40 -0700453 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
454 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
455 m_ts_arr_list[idx].valid = false;
456 }
457 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700458}
459#endif
460
461// factory function executed by the core to create instances
462void *get_omx_component_factory_fn(void)
463{
Arun Menon906de572013-06-18 17:01:40 -0700464 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700465}
466
467#ifdef _ANDROID_
468#ifdef USE_ION
469VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700470 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700471{
Arun Menon906de572013-06-18 17:01:40 -0700472 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700473}
474#else
475VideoHeap::VideoHeap(int fd, size_t size, void* base)
476{
477 // dup file descriptor, map once, use pmem
478 init(dup(fd), base, size, 0 , MEM_DEVICE);
479}
480#endif
481#endif // _ANDROID_
482/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700483 FUNCTION
484 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700485
Arun Menon906de572013-06-18 17:01:40 -0700486 DESCRIPTION
487 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700488
Arun Menon906de572013-06-18 17:01:40 -0700489 PARAMETERS
490 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700491
Arun Menon906de572013-06-18 17:01:40 -0700492 RETURN VALUE
493 None.
494 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800495omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700496 m_state(OMX_StateInvalid),
497 m_app_data(NULL),
498 m_inp_mem_ptr(NULL),
499 m_out_mem_ptr(NULL),
500 m_inp_err_count(0),
501 input_flush_progress (false),
502 output_flush_progress (false),
503 input_use_buffer (false),
504 output_use_buffer (false),
505 ouput_egl_buffers(false),
506 m_use_output_pmem(OMX_FALSE),
507 m_out_mem_region_smi(OMX_FALSE),
508 m_out_pvt_entry_pmem(OMX_FALSE),
509 pending_input_buffers(0),
510 pending_output_buffers(0),
511 m_out_bm_count(0),
512 m_inp_bm_count(0),
513 m_inp_bPopulated(OMX_FALSE),
514 m_out_bPopulated(OMX_FALSE),
515 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700516#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700517 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700518#endif
Arun Menon906de572013-06-18 17:01:40 -0700519 m_inp_bEnabled(OMX_TRUE),
520 m_out_bEnabled(OMX_TRUE),
521 m_in_alloc_cnt(0),
522 m_platform_list(NULL),
523 m_platform_entry(NULL),
524 m_pmem_info(NULL),
525 arbitrary_bytes (true),
526 psource_frame (NULL),
527 pdest_frame (NULL),
528 m_inp_heap_ptr (NULL),
529 m_phdr_pmem_ptr(NULL),
530 m_heap_inp_bm_count (0),
531 codec_type_parse ((codec_type)0),
532 first_frame_meta (true),
533 frame_count (0),
534 nal_count (0),
535 nal_length(0),
536 look_ahead_nal (false),
537 first_frame(0),
538 first_buffer(NULL),
539 first_frame_size (0),
540 m_device_file_ptr(NULL),
541 m_vc1_profile((vc1_profile_type)0),
542 m_profile(0),
543 h264_last_au_ts(LLONG_MAX),
544 h264_last_au_flags(0),
545 prev_ts(LLONG_MAX),
546 rst_prev_ts(true),
547 frm_int(0),
548 m_disp_hor_size(0),
549 m_disp_vert_size(0),
550 in_reconfig(false),
551 m_display_id(NULL),
552 h264_parser(NULL),
553 client_extradata(0),
554 m_reject_avc_1080p_mp (0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700555#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700556 m_enable_android_native_buffers(OMX_FALSE),
557 m_use_android_native_buffers(OMX_FALSE),
558 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700559#endif
Arun Menon906de572013-06-18 17:01:40 -0700560 m_desc_buffer_ptr(NULL),
561 secure_mode(false),
562 client_set_fps(false)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700563{
Arun Menon906de572013-06-18 17:01:40 -0700564 /* Assumption is that , to begin with , we have all the frames with decoder */
565 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700566 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700567#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700568 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700569 property_get("vidc.debug.level", property_value, "0");
570 debug_level = atoi(property_value);
571 property_value[0] = '\0';
572
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700573 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
574
Arun Menon906de572013-06-18 17:01:40 -0700575 property_get("vidc.dec.debug.perf", property_value, "0");
576 perf_flag = atoi(property_value);
577 if (perf_flag) {
578 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
579 dec_time.start();
580 proc_frms = latency = 0;
581 }
582 prev_n_filled_len = 0;
583 property_value[0] = '\0';
584 property_get("vidc.dec.debug.ts", property_value, "0");
585 m_debug_timestamp = atoi(property_value);
586 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
587 if (m_debug_timestamp) {
588 time_stamp_dts.set_timestamp_reorder_mode(true);
589 time_stamp_dts.enable_debug_print(true);
590 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700591
Arun Menon906de572013-06-18 17:01:40 -0700592 property_value[0] = '\0';
593 property_get("vidc.dec.debug.concealedmb", property_value, "0");
594 m_debug_concealedmb = atoi(property_value);
595 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700596
Arun Menon906de572013-06-18 17:01:40 -0700597 property_value[0] = '\0';
598 property_get("vidc.dec.profile.check", property_value, "0");
599 m_reject_avc_1080p_mp = atoi(property_value);
600 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530601
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700602 property_value[0] = '\0';
603 property_get("vidc.dec.log.in", property_value, "0");
604 m_debug.in_buffer_log = atoi(property_value);
605
606 property_value[0] = '\0';
607 property_get("vidc.dec.log.out", property_value, "0");
608 m_debug.out_buffer_log = atoi(property_value);
609 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
610
611 property_value[0] = '\0';
612 property_get("vidc.log.loc", property_value, "");
613 if (*property_value)
614 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700615#endif
Arun Menon906de572013-06-18 17:01:40 -0700616 memset(&m_cmp,0,sizeof(m_cmp));
617 memset(&m_cb,0,sizeof(m_cb));
618 memset (&drv_ctx,0,sizeof(drv_ctx));
619 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
620 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
621 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
622 m_demux_entries = 0;
623 msg_thread_id = 0;
624 async_thread_id = 0;
625 msg_thread_created = false;
626 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700627#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700628 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700629#endif
Arun Menon906de572013-06-18 17:01:40 -0700630 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
631 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#ifdef META_DATA_MODE_SUPPORTED
648 dynamic_buf_mode = false;
649 out_dynamic_list = NULL;
650#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -0700651}
652
Vinay Kalia85793762012-06-14 19:12:34 -0700653static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700654 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
655 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
656 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700657#ifdef META_DATA_MODE_SUPPORTED
658 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
659 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
660#endif
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) {
672 printf("Invalid input: %d\n", fd);
673 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) {
681 printf("Failed to subscribe event: 0x%x\n", sub.type);
682 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)
691 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
692 }
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) {
706 printf("Invalid input: %d\n", fd);
707 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) {
715 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
716 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))
751 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
752 }
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) {
813 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
814 __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;
851 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
852 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) {
859 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
860 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:
872 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
873 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))
882 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
883 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:
895 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
896 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 {
907 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
908 }
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) {
913 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
914 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) {
920 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
921 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) {
928 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
929 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) {
941 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
942 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) {
955 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
956 pThis->omx_report_error ();
957 }
958 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
959 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
960 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) {
976 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
977 pThis->omx_report_error ();
978 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
979 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
980 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
981 pThis->omx_report_error ();
982 }
983 break;
984
985 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
986 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
987 if (!pThis->input_flush_progress) {
988 DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
989 } else {
990 pThis->execute_input_flush();
991 if (pThis->m_cb.EventHandler) {
992 if (p2 != VDEC_S_SUCCESS) {
993 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
994 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);
1000 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
1001 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)) {
1008 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
1009 pThis->omx_report_error ();
1010 } else {
1011 pThis->streaming[OUTPUT_PORT] = false;
1012 }
1013 if (!pThis->output_flush_progress) {
1014 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
1015 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:
1027 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
1028 if (!pThis->output_flush_progress) {
1029 DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
1030 } else {
1031 pThis->execute_output_flush();
1032 if (pThis->m_cb.EventHandler) {
1033 if (p2 != VDEC_S_SUCCESS) {
1034 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1035 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)) {
1040 DEBUG_PRINT_LOW("\n Notify Output Flush done");
1041 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)) {
1048 DEBUG_PRINT_LOW("\n Internal flush complete");
1049 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)) {
1064 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1065 pThis->omx_report_error ();
1066 break;
1067 }
1068 pThis->streaming[CAPTURE_PORT] = false;
1069 if (!pThis->input_flush_progress) {
1070 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
1071 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:
1083 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1084
1085 if (pThis->m_cb.EventHandler) {
1086 if (p2 != VDEC_S_SUCCESS) {
1087 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1088 pThis->omx_report_error ();
1089 } else {
1090 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1091 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1092 DEBUG_PRINT_LOW("\n Move to executing");
1093 // 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) {
1103 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1104 pThis->omx_report_error ();
1105 }
1106 }
1107 }
1108 } else {
1109 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1110 }
1111 break;
1112
1113 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1114 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1115 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)) {
1122 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1123 //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:
1138 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1139 if (pThis->m_cb.EventHandler) {
1140 if (p2 != VDEC_S_SUCCESS) {
1141 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1142 pThis->omx_report_error ();
1143 } else {
1144 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1145 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1146 // 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:
1161 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1162 if (pThis->m_cb.EventHandler) {
1163 if (p2 != VDEC_S_SUCCESS) {
1164 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1165 pThis->omx_report_error ();
1166 } else {
1167 pThis->complete_pending_buffer_done_cbs();
1168 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
1169 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1170 // Send the callback now
1171 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1172 pThis->m_state = OMX_StateIdle;
1173 DEBUG_PRINT_LOW("\n Move to Idle State");
1174 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:
1186 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
1187
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:
1201 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1202 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:
1213 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1214 pThis->omx_report_error ();
1215 break;
1216
1217 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1218 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
1219 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;
1238 if ((height != drv_ctx.video_resolution.frame_height) ||
1239 (width != drv_ctx.video_resolution.frame_width)) {
1240 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)\n",
1241 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 }
1284 DEBUG_PRINT_HIGH("\n video session supported\n");
1285 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) {
1319 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging\n", m_debug.infile_name);
1320 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) {
1374 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging\n", m_debug.outfile);
1375 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";
1446 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001447
Arun Menon906de572013-06-18 17:01:40 -07001448 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001449
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001450 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d",
1451 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001452
Arun Menon906de572013-06-18 17:01:40 -07001453 if (drv_ctx.video_driver_fd == 0) {
1454 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again\n");
1455 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1456 close(0);
1457 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001458
Arun Menon906de572013-06-18 17:01:40 -07001459 if (drv_ctx.video_driver_fd < 0) {
1460 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1461 return OMX_ErrorInsufficientResources;
1462 }
1463 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1464 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001465
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001466 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001467 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001468 async_thread_created = true;
1469 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1470 }
1471 if (ret) {
1472 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1473 async_thread_created = false;
1474 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001475 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001476
Shalaj Jain273b3e02012-06-22 19:08:03 -07001477#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07001478 outputExtradataFile = fopen (ouputextradatafilename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001479#endif
1480
Arun Menon906de572013-06-18 17:01:40 -07001481 // Copy the role information which provides the decoder kind
1482 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001483
Arun Menon906de572013-06-18 17:01:40 -07001484 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1485 OMX_MAX_STRINGNAME_SIZE)) {
1486 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1487 OMX_MAX_STRINGNAME_SIZE);
1488 drv_ctx.timestamp_adjust = true;
1489 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1490 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1491 output_capability=V4L2_PIX_FMT_MPEG4;
1492 /*Initialize Start Code for MPEG4*/
1493 codec_type_parse = CODEC_TYPE_MPEG4;
1494 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001495 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1496 OMX_MAX_STRINGNAME_SIZE)) {
1497 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1498 OMX_MAX_STRINGNAME_SIZE);
1499 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1500 output_capability = V4L2_PIX_FMT_MPEG2;
1501 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1502 /*Initialize Start Code for MPEG2*/
1503 codec_type_parse = CODEC_TYPE_MPEG2;
1504 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001505 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1506 OMX_MAX_STRINGNAME_SIZE)) {
1507 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1508 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1509 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1510 eCompressionFormat = OMX_VIDEO_CodingH263;
1511 output_capability = V4L2_PIX_FMT_H263;
1512 codec_type_parse = CODEC_TYPE_H263;
1513 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001514 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1515 OMX_MAX_STRINGNAME_SIZE)) {
1516 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1517 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1518 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1519 output_capability = V4L2_PIX_FMT_DIVX_311;
1520 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1521 codec_type_parse = CODEC_TYPE_DIVX;
1522 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001523
Arun Menon906de572013-06-18 17:01:40 -07001524 eRet = createDivxDrmContext();
1525 if (eRet != OMX_ErrorNone) {
1526 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1527 return eRet;
1528 }
1529 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1530 OMX_MAX_STRINGNAME_SIZE)) {
1531 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1532 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1533 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1534 output_capability = V4L2_PIX_FMT_DIVX;
1535 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1536 codec_type_parse = CODEC_TYPE_DIVX;
1537 codec_ambiguous = true;
1538 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001539
Arun Menon906de572013-06-18 17:01:40 -07001540 eRet = createDivxDrmContext();
1541 if (eRet != OMX_ErrorNone) {
1542 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1543 return eRet;
1544 }
1545 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1546 OMX_MAX_STRINGNAME_SIZE)) {
1547 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1548 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1549 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1550 output_capability = V4L2_PIX_FMT_DIVX;
1551 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1552 codec_type_parse = CODEC_TYPE_DIVX;
1553 codec_ambiguous = true;
1554 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001555
Arun Menon906de572013-06-18 17:01:40 -07001556 eRet = createDivxDrmContext();
1557 if (eRet != OMX_ErrorNone) {
1558 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1559 return eRet;
1560 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001561
Arun Menon906de572013-06-18 17:01:40 -07001562 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1563 OMX_MAX_STRINGNAME_SIZE)) {
1564 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1565 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1566 output_capability=V4L2_PIX_FMT_H264;
1567 eCompressionFormat = OMX_VIDEO_CodingAVC;
1568 codec_type_parse = CODEC_TYPE_H264;
1569 m_frame_parser.init_start_codes (codec_type_parse);
1570 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001571 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1572 OMX_MAX_STRINGNAME_SIZE)) {
1573 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1574 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1575 eCompressionFormat = OMX_VIDEO_CodingWMV;
1576 codec_type_parse = CODEC_TYPE_VC1;
1577 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1578 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001579 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1580 OMX_MAX_STRINGNAME_SIZE)) {
1581 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1582 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1583 eCompressionFormat = OMX_VIDEO_CodingWMV;
1584 codec_type_parse = CODEC_TYPE_VC1;
1585 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1586 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001587 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1588 OMX_MAX_STRINGNAME_SIZE)) {
1589 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1590 output_capability=V4L2_PIX_FMT_VP8;
1591 eCompressionFormat = OMX_VIDEO_CodingVPX;
1592 codec_type_parse = CODEC_TYPE_VP8;
1593 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001594
Arun Menon906de572013-06-18 17:01:40 -07001595 } else {
1596 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1597 eRet = OMX_ErrorInvalidComponentName;
1598 }
Arun Menon906de572013-06-18 17:01:40 -07001599 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001600
Arun Menon906de572013-06-18 17:01:40 -07001601 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001602 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1603 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1604 if (!client_buffers.set_color_format(dest_color_format)) {
1605 DEBUG_PRINT_ERROR("\n Setting color format failed");
1606 eRet = OMX_ErrorInsufficientResources;
1607 }
1608
Arun Menon906de572013-06-18 17:01:40 -07001609 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001610
Arun Menon906de572013-06-18 17:01:40 -07001611 struct v4l2_capability cap;
1612 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1613 if (ret) {
1614 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
1615 /*TODO: How to handle this case */
1616 } else {
1617 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
1618 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1619 cap.bus_info, cap.version, cap.capabilities);
1620 }
1621 ret=0;
1622 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1623 fdesc.index=0;
1624 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1625 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
1626 fdesc.pixelformat, fdesc.flags);
1627 fdesc.index++;
1628 }
1629 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1630 fdesc.index=0;
1631 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001632
Arun Menon906de572013-06-18 17:01:40 -07001633 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
1634 fdesc.pixelformat, fdesc.flags);
1635 fdesc.index++;
1636 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001637 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001638 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1639 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1640 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1641 fmt.fmt.pix_mp.pixelformat = output_capability;
1642 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1643 if (ret) {
1644 /*TODO: How to handle this case */
1645 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
1646 return OMX_ErrorInsufficientResources;
1647 }
1648 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
1649 if (codec_ambiguous) {
1650 if (output_capability == V4L2_PIX_FMT_DIVX) {
1651 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001652
Arun Menon906de572013-06-18 17:01:40 -07001653 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1654 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1655 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1656 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1657 } else {
1658 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1659 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001660
Arun Menon906de572013-06-18 17:01:40 -07001661 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1662 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1663 if (ret) {
1664 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1665 }
1666 } else {
1667 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1668 }
1669 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001670
Arun Menon906de572013-06-18 17:01:40 -07001671 //Get the hardware capabilities
1672 memset((void *)&frmsize,0,sizeof(frmsize));
1673 frmsize.index = 0;
1674 frmsize.pixel_format = output_capability;
1675 ret = ioctl(drv_ctx.video_driver_fd,
1676 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1677 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1678 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1679 return OMX_ErrorHardware;
1680 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001681
Arun Menon906de572013-06-18 17:01:40 -07001682 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1683 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1684 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1685 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1686 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1687 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001688
Arun Menon906de572013-06-18 17:01:40 -07001689 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1690 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1691 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1692 fmt.fmt.pix_mp.pixelformat = capture_capability;
1693 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1694 if (ret) {
1695 /*TODO: How to handle this case */
1696 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
1697 }
1698 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
1699 if (secure_mode) {
1700 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1701 control.value = 1;
1702 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1703 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1704 if (ret) {
1705 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1706 return OMX_ErrorInsufficientResources;
1707 }
1708 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001709
Arun Menon906de572013-06-18 17:01:40 -07001710 /*Get the Buffer requirements for input and output ports*/
1711 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1712 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1713 if (secure_mode) {
1714 drv_ctx.op_buf.alignment=SZ_1M;
1715 drv_ctx.ip_buf.alignment=SZ_1M;
1716 } else {
1717 drv_ctx.op_buf.alignment=SZ_4K;
1718 drv_ctx.ip_buf.alignment=SZ_4K;
1719 }
1720 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1721 drv_ctx.extradata = 0;
1722 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1723 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1724 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1725 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1726 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001727
Vinay Kalia5713bb32013-01-16 18:39:59 -08001728 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001729#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001730 if (eRet == OMX_ErrorNone && !secure_mode)
1731 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001732#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001733 eRet=get_buffer_req(&drv_ctx.ip_buf);
1734 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1735 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001736 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1737 if (m_frame_parser.mutils == NULL) {
1738 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001739
Arun Menon906de572013-06-18 17:01:40 -07001740 if (m_frame_parser.mutils == NULL) {
1741 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1742 eRet = OMX_ErrorInsufficientResources;
1743 } else {
1744 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1745 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1746 h264_scratch.nFilledLen = 0;
1747 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001748
Arun Menon906de572013-06-18 17:01:40 -07001749 if (h264_scratch.pBuffer == NULL) {
1750 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1751 return OMX_ErrorInsufficientResources;
1752 }
1753 m_frame_parser.mutils->initialize_frame_checking_environment();
1754 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1755 }
1756 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001757
Arun Menon906de572013-06-18 17:01:40 -07001758 h264_parser = new h264_stream_parser();
1759 if (!h264_parser) {
1760 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1761 eRet = OMX_ErrorInsufficientResources;
1762 }
1763 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001764
Arun Menon906de572013-06-18 17:01:40 -07001765 if (pipe(fds)) {
1766 DEBUG_PRINT_ERROR("pipe creation failed\n");
1767 eRet = OMX_ErrorInsufficientResources;
1768 } else {
1769 int temp1[2];
1770 if (fds[0] == 0 || fds[1] == 0) {
1771 if (pipe (temp1)) {
1772 DEBUG_PRINT_ERROR("pipe creation failed\n");
1773 return OMX_ErrorInsufficientResources;
1774 }
1775 //close (fds[0]);
1776 //close (fds[1]);
1777 fds[0] = temp1 [0];
1778 fds[1] = temp1 [1];
1779 }
1780 m_pipe_in = fds[0];
1781 m_pipe_out = fds[1];
1782 msg_thread_created = true;
1783 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001784
Arun Menon906de572013-06-18 17:01:40 -07001785 if (r < 0) {
1786 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1787 msg_thread_created = false;
1788 eRet = OMX_ErrorInsufficientResources;
1789 }
1790 }
1791 }
1792
1793 if (eRet != OMX_ErrorNone) {
1794 DEBUG_PRINT_ERROR("\n Component Init Failed");
1795 } else {
1796 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1797 }
1798 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1799 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001800}
1801
1802/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001803 FUNCTION
1804 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001805
Arun Menon906de572013-06-18 17:01:40 -07001806 DESCRIPTION
1807 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001808
Arun Menon906de572013-06-18 17:01:40 -07001809 PARAMETERS
1810 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001811
Arun Menon906de572013-06-18 17:01:40 -07001812 RETURN VALUE
1813 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001814
Arun Menon906de572013-06-18 17:01:40 -07001815 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001816OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001817(
1818 OMX_IN OMX_HANDLETYPE hComp,
1819 OMX_OUT OMX_STRING componentName,
1820 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1821 OMX_OUT OMX_VERSIONTYPE* specVersion,
1822 OMX_OUT OMX_UUIDTYPE* componentUUID
1823 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001824{
Arun Menon906de572013-06-18 17:01:40 -07001825 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001826 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1827 return OMX_ErrorInvalidState;
1828 }
Arun Menon906de572013-06-18 17:01:40 -07001829 /* TBD -- Return the proper version */
1830 if (specVersion) {
1831 specVersion->nVersion = OMX_SPEC_VERSION;
1832 }
1833 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001834}
1835/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001836 FUNCTION
1837 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001838
Arun Menon906de572013-06-18 17:01:40 -07001839 DESCRIPTION
1840 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001841
Arun Menon906de572013-06-18 17:01:40 -07001842 PARAMETERS
1843 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001844
Arun Menon906de572013-06-18 17:01:40 -07001845 RETURN VALUE
1846 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001847
Arun Menon906de572013-06-18 17:01:40 -07001848 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001849OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001850 OMX_IN OMX_COMMANDTYPE cmd,
1851 OMX_IN OMX_U32 param1,
1852 OMX_IN OMX_PTR cmdData
1853 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001854{
1855 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001856 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001857 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1858 return OMX_ErrorInvalidState;
1859 }
1860 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001861 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
1862 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
1863 "to invalid port: %lu", param1);
1864 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001865 }
1866 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1867 sem_wait(&m_cmd_lock);
1868 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1869 return OMX_ErrorNone;
1870}
1871
1872/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001873 FUNCTION
1874 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001875
Arun Menon906de572013-06-18 17:01:40 -07001876 DESCRIPTION
1877 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001878
Arun Menon906de572013-06-18 17:01:40 -07001879 PARAMETERS
1880 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001881
Arun Menon906de572013-06-18 17:01:40 -07001882 RETURN VALUE
1883 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001884
Arun Menon906de572013-06-18 17:01:40 -07001885 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001886OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001887 OMX_IN OMX_COMMANDTYPE cmd,
1888 OMX_IN OMX_U32 param1,
1889 OMX_IN OMX_PTR cmdData
1890 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001891{
Arun Menon906de572013-06-18 17:01:40 -07001892 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1893 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1894 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001895
Arun Menon906de572013-06-18 17:01:40 -07001896 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1897 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1898 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001899
Arun Menon906de572013-06-18 17:01:40 -07001900 if (cmd == OMX_CommandStateSet) {
1901 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1902 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1903 /***************************/
1904 /* Current State is Loaded */
1905 /***************************/
1906 if (m_state == OMX_StateLoaded) {
1907 if (eState == OMX_StateIdle) {
1908 //if all buffers are allocated or all ports disabled
1909 if (allocate_done() ||
1910 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
1911 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1912 } else {
1913 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1914 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1915 // Skip the event notification
1916 bFlag = 0;
1917 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001918 }
Arun Menon906de572013-06-18 17:01:40 -07001919 /* Requesting transition from Loaded to Loaded */
1920 else if (eState == OMX_StateLoaded) {
1921 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1922 post_event(OMX_EventError,OMX_ErrorSameState,\
1923 OMX_COMPONENT_GENERATE_EVENT);
1924 eRet = OMX_ErrorSameState;
1925 }
1926 /* Requesting transition from Loaded to WaitForResources */
1927 else if (eState == OMX_StateWaitForResources) {
1928 /* Since error is None , we will post an event
1929 at the end of this function definition */
1930 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1931 }
1932 /* Requesting transition from Loaded to Executing */
1933 else if (eState == OMX_StateExecuting) {
1934 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1935 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1936 OMX_COMPONENT_GENERATE_EVENT);
1937 eRet = OMX_ErrorIncorrectStateTransition;
1938 }
1939 /* Requesting transition from Loaded to Pause */
1940 else if (eState == OMX_StatePause) {
1941 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1942 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1943 OMX_COMPONENT_GENERATE_EVENT);
1944 eRet = OMX_ErrorIncorrectStateTransition;
1945 }
1946 /* Requesting transition from Loaded to Invalid */
1947 else if (eState == OMX_StateInvalid) {
1948 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1949 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1950 eRet = OMX_ErrorInvalidState;
1951 } else {
1952 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1953 eState);
1954 eRet = OMX_ErrorBadParameter;
1955 }
1956 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001957
Arun Menon906de572013-06-18 17:01:40 -07001958 /***************************/
1959 /* Current State is IDLE */
1960 /***************************/
1961 else if (m_state == OMX_StateIdle) {
1962 if (eState == OMX_StateLoaded) {
1963 if (release_done()) {
1964 /*
1965 Since error is None , we will post an event at the end
1966 of this function definition
1967 */
1968 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
1969 } else {
1970 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
1971 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1972 // Skip the event notification
1973 bFlag = 0;
1974 }
1975 }
1976 /* Requesting transition from Idle to Executing */
1977 else if (eState == OMX_StateExecuting) {
1978 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1979 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1980 bFlag = 1;
1981 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1982 m_state=OMX_StateExecuting;
1983 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
1984 }
1985 /* Requesting transition from Idle to Idle */
1986 else if (eState == OMX_StateIdle) {
1987 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
1988 post_event(OMX_EventError,OMX_ErrorSameState,\
1989 OMX_COMPONENT_GENERATE_EVENT);
1990 eRet = OMX_ErrorSameState;
1991 }
1992 /* Requesting transition from Idle to WaitForResources */
1993 else if (eState == OMX_StateWaitForResources) {
1994 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
1995 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1996 OMX_COMPONENT_GENERATE_EVENT);
1997 eRet = OMX_ErrorIncorrectStateTransition;
1998 }
1999 /* Requesting transition from Idle to Pause */
2000 else if (eState == OMX_StatePause) {
2001 /*To pause the Video core we need to start the driver*/
2002 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2003 NULL) < */0) {
2004 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
2005 omx_report_error ();
2006 eRet = OMX_ErrorHardware;
2007 } else {
2008 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2009 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
2010 bFlag = 0;
2011 }
2012 }
2013 /* Requesting transition from Idle to Invalid */
2014 else if (eState == OMX_StateInvalid) {
2015 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
2016 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2017 eRet = OMX_ErrorInvalidState;
2018 } else {
2019 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
2020 eRet = OMX_ErrorBadParameter;
2021 }
2022 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002023
Arun Menon906de572013-06-18 17:01:40 -07002024 /******************************/
2025 /* Current State is Executing */
2026 /******************************/
2027 else if (m_state == OMX_StateExecuting) {
2028 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
2029 /* Requesting transition from Executing to Idle */
2030 if (eState == OMX_StateIdle) {
2031 /* Since error is None , we will post an event
2032 at the end of this function definition
2033 */
2034 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
2035 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2036 if (!sem_posted) {
2037 sem_posted = 1;
2038 sem_post (&m_cmd_lock);
2039 execute_omx_flush(OMX_ALL);
2040 }
2041 bFlag = 0;
2042 }
2043 /* Requesting transition from Executing to Paused */
2044 else if (eState == OMX_StatePause) {
2045 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
2046 m_state = OMX_StatePause;
2047 bFlag = 1;
2048 }
2049 /* Requesting transition from Executing to Loaded */
2050 else if (eState == OMX_StateLoaded) {
2051 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2052 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2053 OMX_COMPONENT_GENERATE_EVENT);
2054 eRet = OMX_ErrorIncorrectStateTransition;
2055 }
2056 /* Requesting transition from Executing to WaitForResources */
2057 else if (eState == OMX_StateWaitForResources) {
2058 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2059 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2060 OMX_COMPONENT_GENERATE_EVENT);
2061 eRet = OMX_ErrorIncorrectStateTransition;
2062 }
2063 /* Requesting transition from Executing to Executing */
2064 else if (eState == OMX_StateExecuting) {
2065 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2066 post_event(OMX_EventError,OMX_ErrorSameState,\
2067 OMX_COMPONENT_GENERATE_EVENT);
2068 eRet = OMX_ErrorSameState;
2069 }
2070 /* Requesting transition from Executing to Invalid */
2071 else if (eState == OMX_StateInvalid) {
2072 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2073 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2074 eRet = OMX_ErrorInvalidState;
2075 } else {
2076 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2077 eRet = OMX_ErrorBadParameter;
2078 }
2079 }
2080 /***************************/
2081 /* Current State is Pause */
2082 /***************************/
2083 else if (m_state == OMX_StatePause) {
2084 /* Requesting transition from Pause to Executing */
2085 if (eState == OMX_StateExecuting) {
2086 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
2087 m_state = OMX_StateExecuting;
2088 bFlag = 1;
2089 }
2090 /* Requesting transition from Pause to Idle */
2091 else if (eState == OMX_StateIdle) {
2092 /* Since error is None , we will post an event
2093 at the end of this function definition */
2094 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2095 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2096 if (!sem_posted) {
2097 sem_posted = 1;
2098 sem_post (&m_cmd_lock);
2099 execute_omx_flush(OMX_ALL);
2100 }
2101 bFlag = 0;
2102 }
2103 /* Requesting transition from Pause to loaded */
2104 else if (eState == OMX_StateLoaded) {
2105 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2106 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2107 OMX_COMPONENT_GENERATE_EVENT);
2108 eRet = OMX_ErrorIncorrectStateTransition;
2109 }
2110 /* Requesting transition from Pause to WaitForResources */
2111 else if (eState == OMX_StateWaitForResources) {
2112 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2113 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2114 OMX_COMPONENT_GENERATE_EVENT);
2115 eRet = OMX_ErrorIncorrectStateTransition;
2116 }
2117 /* Requesting transition from Pause to Pause */
2118 else if (eState == OMX_StatePause) {
2119 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2120 post_event(OMX_EventError,OMX_ErrorSameState,\
2121 OMX_COMPONENT_GENERATE_EVENT);
2122 eRet = OMX_ErrorSameState;
2123 }
2124 /* Requesting transition from Pause to Invalid */
2125 else if (eState == OMX_StateInvalid) {
2126 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2127 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2128 eRet = OMX_ErrorInvalidState;
2129 } else {
2130 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2131 eRet = OMX_ErrorBadParameter;
2132 }
2133 }
2134 /***************************/
2135 /* Current State is WaitForResources */
2136 /***************************/
2137 else if (m_state == OMX_StateWaitForResources) {
2138 /* Requesting transition from WaitForResources to Loaded */
2139 if (eState == OMX_StateLoaded) {
2140 /* Since error is None , we will post an event
2141 at the end of this function definition */
2142 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2143 }
2144 /* Requesting transition from WaitForResources to WaitForResources */
2145 else if (eState == OMX_StateWaitForResources) {
2146 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2147 post_event(OMX_EventError,OMX_ErrorSameState,
2148 OMX_COMPONENT_GENERATE_EVENT);
2149 eRet = OMX_ErrorSameState;
2150 }
2151 /* Requesting transition from WaitForResources to Executing */
2152 else if (eState == OMX_StateExecuting) {
2153 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2154 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2155 OMX_COMPONENT_GENERATE_EVENT);
2156 eRet = OMX_ErrorIncorrectStateTransition;
2157 }
2158 /* Requesting transition from WaitForResources to Pause */
2159 else if (eState == OMX_StatePause) {
2160 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2161 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2162 OMX_COMPONENT_GENERATE_EVENT);
2163 eRet = OMX_ErrorIncorrectStateTransition;
2164 }
2165 /* Requesting transition from WaitForResources to Invalid */
2166 else if (eState == OMX_StateInvalid) {
2167 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2168 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2169 eRet = OMX_ErrorInvalidState;
2170 }
2171 /* Requesting transition from WaitForResources to Loaded -
2172 is NOT tested by Khronos TS */
2173
2174 } else {
2175 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2176 eRet = OMX_ErrorBadParameter;
2177 }
2178 }
2179 /********************************/
2180 /* Current State is Invalid */
2181 /*******************************/
2182 else if (m_state == OMX_StateInvalid) {
2183 /* State Transition from Inavlid to any state */
2184 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2185 || OMX_StateIdle || OMX_StateExecuting
2186 || OMX_StatePause || OMX_StateInvalid)) {
2187 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2188 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2189 OMX_COMPONENT_GENERATE_EVENT);
2190 eRet = OMX_ErrorInvalidState;
2191 }
2192 } else if (cmd == OMX_CommandFlush) {
2193 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
2194 "with param1: %lu", param1);
2195 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2196 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2197 }
2198 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2199 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2200 }
2201 if (!sem_posted) {
2202 sem_posted = 1;
2203 DEBUG_PRINT_LOW("\n Set the Semaphore");
2204 sem_post (&m_cmd_lock);
2205 execute_omx_flush(param1);
2206 }
2207 bFlag = 0;
2208 } else if ( cmd == OMX_CommandPortEnable) {
2209 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
2210 "with param1: %lu", param1);
2211 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2212 m_inp_bEnabled = OMX_TRUE;
2213
2214 if ( (m_state == OMX_StateLoaded &&
2215 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2216 || allocate_input_done()) {
2217 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2218 OMX_COMPONENT_GENERATE_EVENT);
2219 } else {
2220 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2221 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2222 // Skip the event notification
2223 bFlag = 0;
2224 }
2225 }
2226 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2227 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2228 m_out_bEnabled = OMX_TRUE;
2229
2230 if ( (m_state == OMX_StateLoaded &&
2231 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2232 || (allocate_output_done())) {
2233 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2234 OMX_COMPONENT_GENERATE_EVENT);
2235
2236 } else {
2237 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2238 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2239 // Skip the event notification
2240 bFlag = 0;
2241 }
2242 }
2243 } else if (cmd == OMX_CommandPortDisable) {
2244 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
2245 "with param1: %lu", param1);
2246 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2247 m_inp_bEnabled = OMX_FALSE;
2248 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2249 && release_input_done()) {
2250 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2251 OMX_COMPONENT_GENERATE_EVENT);
2252 } else {
2253 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2254 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2255 if (!sem_posted) {
2256 sem_posted = 1;
2257 sem_post (&m_cmd_lock);
2258 }
2259 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2260 }
2261
2262 // Skip the event notification
2263 bFlag = 0;
2264 }
2265 }
2266 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2267 m_out_bEnabled = OMX_FALSE;
2268 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2269 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2270 && release_output_done()) {
2271 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2272 OMX_COMPONENT_GENERATE_EVENT);
2273 } else {
2274 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2275 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2276 if (!sem_posted) {
2277 sem_posted = 1;
2278 sem_post (&m_cmd_lock);
2279 }
2280 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2281 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2282 }
2283 // Skip the event notification
2284 bFlag = 0;
2285
2286 }
2287 }
2288 } else {
2289 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2290 eRet = OMX_ErrorNotImplemented;
2291 }
2292 if (eRet == OMX_ErrorNone && bFlag) {
2293 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2294 }
2295 if (!sem_posted) {
2296 sem_post(&m_cmd_lock);
2297 }
2298
2299 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002300}
2301
2302/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002303 FUNCTION
2304 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002305
Arun Menon906de572013-06-18 17:01:40 -07002306 DESCRIPTION
2307 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002308
Arun Menon906de572013-06-18 17:01:40 -07002309 PARAMETERS
2310 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002311
Arun Menon906de572013-06-18 17:01:40 -07002312 RETURN VALUE
2313 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002314
Arun Menon906de572013-06-18 17:01:40 -07002315 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002316bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2317{
Arun Menon906de572013-06-18 17:01:40 -07002318 bool bRet = false;
2319 struct v4l2_plane plane;
2320 struct v4l2_buffer v4l2_buf;
2321 struct v4l2_decoder_cmd dec;
2322 DEBUG_PRINT_LOW("in %s, flushing %d", __func__, flushType);
2323 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2324 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002325
Arun Menon906de572013-06-18 17:01:40 -07002326 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002327
Arun Menon906de572013-06-18 17:01:40 -07002328 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2329 output_flush_progress = true;
2330 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2331 } else {
2332 /* XXX: The driver/hardware does not support flushing of individual ports
2333 * in all states. So we pretty much need to flush both ports internally,
2334 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2335 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2336 * we automatically omit sending the FLUSH done for the "opposite" port. */
2337 input_flush_progress = true;
2338 output_flush_progress = true;
2339 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2340 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002341
Arun Menon906de572013-06-18 17:01:40 -07002342 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
2343 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
2344 bRet = false;
2345 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002346
Arun Menon906de572013-06-18 17:01:40 -07002347 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002348}
2349/*=========================================================================
2350FUNCTION : execute_output_flush
2351
2352DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002353Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002354
2355PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002356None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002357
2358RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002359true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002360==========================================================================*/
2361bool omx_vdec::execute_output_flush()
2362{
Arun Menon906de572013-06-18 17:01:40 -07002363 unsigned p1 = 0; // Parameter - 1
2364 unsigned p2 = 0; // Parameter - 2
2365 unsigned ident = 0;
2366 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002367
Arun Menon906de572013-06-18 17:01:40 -07002368 /*Generate FBD for all Buffers in the FTBq*/
2369 pthread_mutex_lock(&m_lock);
2370 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2371 while (m_ftb_q.m_size) {
2372 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2373 m_ftb_q.m_size,pending_output_buffers);
2374 m_ftb_q.pop_entry(&p1,&p2,&ident);
2375 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
2376 if (ident == m_fill_output_msg ) {
2377 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2378 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2379 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2380 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002381 }
Arun Menon906de572013-06-18 17:01:40 -07002382 pthread_mutex_unlock(&m_lock);
2383 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002384
Arun Menon906de572013-06-18 17:01:40 -07002385 if (arbitrary_bytes) {
2386 prev_ts = LLONG_MAX;
2387 rst_prev_ts = true;
2388 }
2389 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2390 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002391}
2392/*=========================================================================
2393FUNCTION : execute_input_flush
2394
2395DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002396Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002397
2398PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002399None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002400
2401RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002402true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002403==========================================================================*/
2404bool omx_vdec::execute_input_flush()
2405{
Arun Menon906de572013-06-18 17:01:40 -07002406 unsigned i =0;
2407 unsigned p1 = 0; // Parameter - 1
2408 unsigned p2 = 0; // Parameter - 2
2409 unsigned ident = 0;
2410 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002411
Arun Menon906de572013-06-18 17:01:40 -07002412 /*Generate EBD for all Buffers in the ETBq*/
2413 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002414
Arun Menon906de572013-06-18 17:01:40 -07002415 pthread_mutex_lock(&m_lock);
2416 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2417 while (m_etb_q.m_size) {
2418 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002419
Arun Menon906de572013-06-18 17:01:40 -07002420 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2421 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2422 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2423 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2424 pending_input_buffers++;
2425 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2426 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2427 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2428 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
2429 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2430 (OMX_BUFFERHEADERTYPE *)p1);
2431 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2432 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002433 }
Arun Menon906de572013-06-18 17:01:40 -07002434 time_stamp_dts.flush_timestamp();
2435 /*Check if Heap Buffers are to be flushed*/
2436 if (arbitrary_bytes && !(codec_config_flag)) {
2437 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2438 h264_scratch.nFilledLen = 0;
2439 nal_count = 0;
2440 look_ahead_nal = false;
2441 frame_count = 0;
2442 h264_last_au_ts = LLONG_MAX;
2443 h264_last_au_flags = 0;
2444 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2445 m_demux_entries = 0;
2446 DEBUG_PRINT_LOW("\n Initialize parser");
2447 if (m_frame_parser.mutils) {
2448 m_frame_parser.mutils->initialize_frame_checking_environment();
2449 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002450
Arun Menon906de572013-06-18 17:01:40 -07002451 while (m_input_pending_q.m_size) {
2452 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2453 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2454 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002455
Arun Menon906de572013-06-18 17:01:40 -07002456 if (psource_frame) {
2457 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2458 psource_frame = NULL;
2459 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002460
Arun Menon906de572013-06-18 17:01:40 -07002461 if (pdest_frame) {
2462 pdest_frame->nFilledLen = 0;
2463 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2464 (unsigned int)NULL);
2465 pdest_frame = NULL;
2466 }
2467 m_frame_parser.flush();
2468 } else if (codec_config_flag) {
2469 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2470 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002471 }
Arun Menon906de572013-06-18 17:01:40 -07002472 pthread_mutex_unlock(&m_lock);
2473 input_flush_progress = false;
2474 if (!arbitrary_bytes) {
2475 prev_ts = LLONG_MAX;
2476 rst_prev_ts = true;
2477 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002478#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002479 if (m_debug_timestamp) {
2480 m_timestamp_list.reset_ts_list();
2481 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002482#endif
Arun Menon906de572013-06-18 17:01:40 -07002483 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2484 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002485}
2486
2487
2488/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002489 FUNCTION
2490 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002491
Arun Menon906de572013-06-18 17:01:40 -07002492 DESCRIPTION
2493 Send the event to decoder pipe. This is needed to generate the callbacks
2494 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002495
Arun Menon906de572013-06-18 17:01:40 -07002496 PARAMETERS
2497 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002498
Arun Menon906de572013-06-18 17:01:40 -07002499 RETURN VALUE
2500 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002501
Arun Menon906de572013-06-18 17:01:40 -07002502 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002503bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002504 unsigned int p2,
2505 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002506{
Arun Menon906de572013-06-18 17:01:40 -07002507 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002508
2509
Arun Menon906de572013-06-18 17:01:40 -07002510 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002511
Arun Menon906de572013-06-18 17:01:40 -07002512 if (id == m_fill_output_msg ||
2513 id == OMX_COMPONENT_GENERATE_FBD) {
2514 m_ftb_q.insert_entry(p1,p2,id);
2515 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2516 id == OMX_COMPONENT_GENERATE_EBD ||
2517 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2518 m_etb_q.insert_entry(p1,p2,id);
2519 } else {
2520 m_cmd_q.insert_entry(p1,p2,id);
2521 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002522
Arun Menon906de572013-06-18 17:01:40 -07002523 bRet = true;
2524 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2525 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002526
Arun Menon906de572013-06-18 17:01:40 -07002527 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002528
Arun Menon906de572013-06-18 17:01:40 -07002529 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002530}
2531
2532OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2533{
Arun Menon906de572013-06-18 17:01:40 -07002534 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2535 if (!profileLevelType)
2536 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002537
Arun Menon906de572013-06-18 17:01:40 -07002538 if (profileLevelType->nPortIndex == 0) {
2539 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2540 if (profileLevelType->nProfileIndex == 0) {
2541 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2542 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002543
Arun Menon906de572013-06-18 17:01:40 -07002544 } else if (profileLevelType->nProfileIndex == 1) {
2545 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2546 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2547 } else if (profileLevelType->nProfileIndex == 2) {
2548 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2549 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2550 } else {
2551 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
2552 profileLevelType->nProfileIndex);
2553 eRet = OMX_ErrorNoMore;
2554 }
2555 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2556 if (profileLevelType->nProfileIndex == 0) {
2557 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2558 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2559 } else {
2560 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2561 eRet = OMX_ErrorNoMore;
2562 }
2563 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2564 if (profileLevelType->nProfileIndex == 0) {
2565 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2566 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2567 } else if (profileLevelType->nProfileIndex == 1) {
2568 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2569 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2570 } else {
2571 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2572 eRet = OMX_ErrorNoMore;
2573 }
2574 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2575 eRet = OMX_ErrorNoMore;
2576 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2577 if (profileLevelType->nProfileIndex == 0) {
2578 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2579 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2580 } else if (profileLevelType->nProfileIndex == 1) {
2581 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2582 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2583 } else {
2584 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2585 eRet = OMX_ErrorNoMore;
2586 }
2587 } else {
2588 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s\n", drv_ctx.kind);
2589 eRet = OMX_ErrorNoMore;
2590 }
2591 } else {
2592 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex);
2593 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002594 }
Arun Menon906de572013-06-18 17:01:40 -07002595 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002596}
2597
2598/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002599 FUNCTION
2600 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002601
Arun Menon906de572013-06-18 17:01:40 -07002602 DESCRIPTION
2603 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002604
Arun Menon906de572013-06-18 17:01:40 -07002605 PARAMETERS
2606 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002607
Arun Menon906de572013-06-18 17:01:40 -07002608 RETURN VALUE
2609 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002610
Arun Menon906de572013-06-18 17:01:40 -07002611 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002612OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002613 OMX_IN OMX_INDEXTYPE paramIndex,
2614 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002615{
2616 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2617
2618 DEBUG_PRINT_LOW("get_parameter: \n");
Arun Menon906de572013-06-18 17:01:40 -07002619 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002620 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2621 return OMX_ErrorInvalidState;
2622 }
Arun Menon906de572013-06-18 17:01:40 -07002623 if (paramData == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002624 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2625 return OMX_ErrorBadParameter;
2626 }
Arun Menon906de572013-06-18 17:01:40 -07002627 switch ((unsigned long)paramIndex) {
2628 case OMX_IndexParamPortDefinition: {
2629 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2630 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2631 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2632 eRet = update_portdef(portDefn);
2633 if (eRet == OMX_ErrorNone)
2634 m_port_def = *portDefn;
2635 break;
2636 }
2637 case OMX_IndexParamVideoInit: {
2638 OMX_PORT_PARAM_TYPE *portParamType =
2639 (OMX_PORT_PARAM_TYPE *) paramData;
2640 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002641
Arun Menon906de572013-06-18 17:01:40 -07002642 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2643 portParamType->nSize = sizeof(portParamType);
2644 portParamType->nPorts = 2;
2645 portParamType->nStartPortNumber = 0;
2646 break;
2647 }
2648 case OMX_IndexParamVideoPortFormat: {
2649 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2650 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2651 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002652
Arun Menon906de572013-06-18 17:01:40 -07002653 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2654 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002655
Arun Menon906de572013-06-18 17:01:40 -07002656 if (0 == portFmt->nPortIndex) {
2657 if (0 == portFmt->nIndex) {
2658 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2659 portFmt->eCompressionFormat = eCompressionFormat;
2660 } else {
2661 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2662 " NoMore compression formats\n");
2663 eRet = OMX_ErrorNoMore;
2664 }
2665 } else if (1 == portFmt->nPortIndex) {
2666 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002667
Arun Menon906de572013-06-18 17:01:40 -07002668 if (0 == portFmt->nIndex)
2669 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2670 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2671 else if (1 == portFmt->nIndex)
2672 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2673 else {
2674 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2675 " NoMore Color formats\n");
2676 eRet = OMX_ErrorNoMore;
2677 }
2678 DEBUG_PRINT_LOW("returning %d\n", portFmt->eColorFormat);
2679 } else {
2680 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2681 (int)portFmt->nPortIndex);
2682 eRet = OMX_ErrorBadPortIndex;
2683 }
2684 break;
2685 }
2686 /*Component should support this port definition*/
2687 case OMX_IndexParamAudioInit: {
2688 OMX_PORT_PARAM_TYPE *audioPortParamType =
2689 (OMX_PORT_PARAM_TYPE *) paramData;
2690 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2691 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2692 audioPortParamType->nSize = sizeof(audioPortParamType);
2693 audioPortParamType->nPorts = 0;
2694 audioPortParamType->nStartPortNumber = 0;
2695 break;
2696 }
2697 /*Component should support this port definition*/
2698 case OMX_IndexParamImageInit: {
2699 OMX_PORT_PARAM_TYPE *imagePortParamType =
2700 (OMX_PORT_PARAM_TYPE *) paramData;
2701 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2702 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2703 imagePortParamType->nSize = sizeof(imagePortParamType);
2704 imagePortParamType->nPorts = 0;
2705 imagePortParamType->nStartPortNumber = 0;
2706 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002707
Arun Menon906de572013-06-18 17:01:40 -07002708 }
2709 /*Component should support this port definition*/
2710 case OMX_IndexParamOtherInit: {
2711 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2712 paramIndex);
2713 eRet =OMX_ErrorUnsupportedIndex;
2714 break;
2715 }
2716 case OMX_IndexParamStandardComponentRole: {
2717 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2718 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2719 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2720 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002721
Arun Menon906de572013-06-18 17:01:40 -07002722 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2723 paramIndex);
2724 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2725 OMX_MAX_STRINGNAME_SIZE);
2726 break;
2727 }
2728 /* Added for parameter test */
2729 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002730
Arun Menon906de572013-06-18 17:01:40 -07002731 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2732 (OMX_PRIORITYMGMTTYPE *) paramData;
2733 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2734 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2735 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002736
Arun Menon906de572013-06-18 17:01:40 -07002737 break;
2738 }
2739 /* Added for parameter test */
2740 case OMX_IndexParamCompBufferSupplier: {
2741 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2742 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2743 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002744
Arun Menon906de572013-06-18 17:01:40 -07002745 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2746 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2747 if (0 == bufferSupplierType->nPortIndex)
2748 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2749 else if (1 == bufferSupplierType->nPortIndex)
2750 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2751 else
2752 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002753
2754
Arun Menon906de572013-06-18 17:01:40 -07002755 break;
2756 }
2757 case OMX_IndexParamVideoAvc: {
2758 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2759 paramIndex);
2760 break;
2761 }
2762 case OMX_IndexParamVideoH263: {
2763 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2764 paramIndex);
2765 break;
2766 }
2767 case OMX_IndexParamVideoMpeg4: {
2768 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2769 paramIndex);
2770 break;
2771 }
2772 case OMX_IndexParamVideoMpeg2: {
2773 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2774 paramIndex);
2775 break;
2776 }
2777 case OMX_IndexParamVideoProfileLevelQuerySupported: {
2778 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2779 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2780 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2781 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2782 break;
2783 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002784#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002785 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
2786 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2787 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2788 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002789
Arun Menon906de572013-06-18 17:01:40 -07002790 if (secure_mode) {
2791 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2792 GRALLOC_USAGE_PRIVATE_UNCACHED);
2793 } else {
2794 nativeBuffersUsage->nUsage =
2795 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2796 GRALLOC_USAGE_PRIVATE_UNCACHED);
2797 }
2798 } else {
2799 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
2800 eRet = OMX_ErrorBadParameter;
2801 }
2802 }
2803 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002804#endif
2805
Arun Menon906de572013-06-18 17:01:40 -07002806 default: {
2807 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2808 eRet =OMX_ErrorUnsupportedIndex;
2809 }
2810
Shalaj Jain273b3e02012-06-22 19:08:03 -07002811 }
2812
Arun Menon906de572013-06-18 17:01:40 -07002813 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
2814 drv_ctx.video_resolution.frame_width,
2815 drv_ctx.video_resolution.frame_height,
2816 drv_ctx.video_resolution.stride,
2817 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002818
Arun Menon906de572013-06-18 17:01:40 -07002819 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002820}
2821
2822#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2823OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2824{
2825 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2826 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2827 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2828
Arun Menon906de572013-06-18 17:01:40 -07002829 if ((params == NULL) ||
2830 (params->nativeBuffer == NULL) ||
2831 (params->nativeBuffer->handle == NULL) ||
2832 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002833 return OMX_ErrorBadParameter;
2834 m_use_android_native_buffers = OMX_TRUE;
2835 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2836 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002837 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 -07002838 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002839 if (!secure_mode) {
2840 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002841 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002842 if (buffer == MAP_FAILED) {
2843 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2844 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002845 }
2846 }
2847 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2848 } else {
2849 eRet = OMX_ErrorBadParameter;
2850 }
2851 return eRet;
2852}
2853#endif
2854/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002855 FUNCTION
2856 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002857
Arun Menon906de572013-06-18 17:01:40 -07002858 DESCRIPTION
2859 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002860
Arun Menon906de572013-06-18 17:01:40 -07002861 PARAMETERS
2862 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002863
Arun Menon906de572013-06-18 17:01:40 -07002864 RETURN VALUE
2865 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002866
Arun Menon906de572013-06-18 17:01:40 -07002867 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002868OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002869 OMX_IN OMX_INDEXTYPE paramIndex,
2870 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002871{
2872 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002873 int ret=0;
2874 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002875 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002876 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
2877 return OMX_ErrorInvalidState;
2878 }
Arun Menon906de572013-06-18 17:01:40 -07002879 if (paramData == NULL) {
2880 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
2881 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002882 }
Arun Menon906de572013-06-18 17:01:40 -07002883 if ((m_state != OMX_StateLoaded) &&
2884 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2885 (m_out_bEnabled == OMX_TRUE) &&
2886 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2887 (m_inp_bEnabled == OMX_TRUE)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002888 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
2889 return OMX_ErrorIncorrectStateOperation;
2890 }
Arun Menon906de572013-06-18 17:01:40 -07002891 switch ((unsigned long)paramIndex) {
2892 case OMX_IndexParamPortDefinition: {
2893 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2894 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2895 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2896 //been called.
2897 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
2898 (int)portDefn->format.video.nFrameHeight,
2899 (int)portDefn->format.video.nFrameWidth);
2900 if (OMX_DirOutput == portDefn->eDir) {
2901 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
2902 m_display_id = portDefn->format.video.pNativeWindow;
2903 unsigned int buffer_size;
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07002904 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
2905 portDefn->format.video.nFrameWidth,
2906 portDefn->format.video.nFrameHeight);
2907 if (portDefn->format.video.nFrameHeight != 0x0 &&
2908 portDefn->format.video.nFrameWidth != 0x0) {
2909 update_resolution(portDefn->format.video.nFrameWidth,
2910 portDefn->format.video.nFrameHeight,
2911 portDefn->format.video.nFrameWidth,
2912 portDefn->format.video.nFrameHeight);
2913 eRet = is_video_session_supported();
2914 if (eRet)
2915 break;
2916 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2917 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2918 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2919 fmt.fmt.pix_mp.pixelformat = capture_capability;
2920 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);
2921 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2922 if (ret) {
2923 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2924 eRet = OMX_ErrorUnsupportedSetting;
2925 } else
2926 eRet = get_buffer_req(&drv_ctx.op_buf);
2927 }
2928
Arun Menon906de572013-06-18 17:01:40 -07002929 if (!client_buffers.get_buffer_req(buffer_size)) {
2930 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
2931 eRet = OMX_ErrorBadParameter;
2932 } else {
2933 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
2934 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
2935 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
2936 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
2937 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
2938 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
2939 drv_ctx.extradata_info.buffer_size;
2940 eRet = set_buffer_req(&drv_ctx.op_buf);
2941 if (eRet == OMX_ErrorNone)
2942 m_port_def = *portDefn;
2943 } else {
2944 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
2945 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
2946 portDefn->nBufferCountActual, portDefn->nBufferSize);
2947 eRet = OMX_ErrorBadParameter;
2948 }
2949 }
2950 } else if (OMX_DirInput == portDefn->eDir) {
2951 bool port_format_changed = false;
2952 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
2953 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
2954 // Frame rate only should be set if this is a "known value" or to
2955 // activate ts prediction logic (arbitrary mode only) sending input
2956 // timestamps with max value (LLONG_MAX).
2957 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
2958 portDefn->format.video.xFramerate >> 16);
2959 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
2960 drv_ctx.frame_rate.fps_denominator);
2961 if (!drv_ctx.frame_rate.fps_numerator) {
2962 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
2963 drv_ctx.frame_rate.fps_numerator = 30;
2964 }
2965 if (drv_ctx.frame_rate.fps_denominator)
2966 drv_ctx.frame_rate.fps_numerator = (int)
2967 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
2968 drv_ctx.frame_rate.fps_denominator = 1;
2969 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
2970 drv_ctx.frame_rate.fps_numerator;
2971 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
2972 frm_int, drv_ctx.frame_rate.fps_numerator /
2973 (float)drv_ctx.frame_rate.fps_denominator);
2974 }
2975 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
2976 if (drv_ctx.video_resolution.frame_height !=
2977 portDefn->format.video.nFrameHeight ||
2978 drv_ctx.video_resolution.frame_width !=
2979 portDefn->format.video.nFrameWidth) {
2980 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
2981 portDefn->format.video.nFrameWidth,
2982 portDefn->format.video.nFrameHeight);
2983 port_format_changed = true;
2984 if (portDefn->format.video.nFrameHeight != 0x0 &&
2985 portDefn->format.video.nFrameWidth != 0x0) {
2986 update_resolution(portDefn->format.video.nFrameWidth,
2987 portDefn->format.video.nFrameHeight,
2988 portDefn->format.video.nFrameWidth,
2989 portDefn->format.video.nFrameHeight);
2990 eRet = is_video_session_supported();
2991 if (eRet)
2992 break;
2993 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2994 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2995 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2996 fmt.fmt.pix_mp.pixelformat = output_capability;
2997 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);
2998 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2999 if (ret) {
3000 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3001 eRet = OMX_ErrorUnsupportedSetting;
3002 } else
3003 eRet = get_buffer_req(&drv_ctx.op_buf);
3004 }
3005 }
3006 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3007 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3008 port_format_changed = true;
3009 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3010 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3011 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3012 (~(buffer_prop->alignment - 1));
3013 eRet = set_buffer_req(buffer_prop);
3014 }
3015 if (false == port_format_changed) {
3016 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
3017 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3018 portDefn->nBufferCountActual, portDefn->nBufferSize);
3019 eRet = OMX_ErrorBadParameter;
3020 }
3021 } else if (portDefn->eDir == OMX_DirMax) {
3022 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3023 (int)portDefn->nPortIndex);
3024 eRet = OMX_ErrorBadPortIndex;
3025 }
3026 }
3027 break;
3028 case OMX_IndexParamVideoPortFormat: {
3029 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3030 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3031 int ret=0;
3032 struct v4l2_format fmt;
3033 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3034 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003035
Arun Menon906de572013-06-18 17:01:40 -07003036 if (1 == portFmt->nPortIndex) {
3037 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3038 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3039 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3040 fmt.fmt.pix_mp.pixelformat = capture_capability;
3041 enum vdec_output_fromat op_format;
3042 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3043 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
3044 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
3045 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
3046 else if (portFmt->eColorFormat ==
3047 (OMX_COLOR_FORMATTYPE)
3048 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3049 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3050 else
3051 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003052
Arun Menon906de572013-06-18 17:01:40 -07003053 if (eRet == OMX_ErrorNone) {
3054 drv_ctx.output_format = op_format;
3055 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3056 if (ret) {
3057 DEBUG_PRINT_ERROR("\n Set output format failed");
3058 eRet = OMX_ErrorUnsupportedSetting;
3059 /*TODO: How to handle this case */
3060 } else {
3061 eRet = get_buffer_req(&drv_ctx.op_buf);
3062 }
3063 }
3064 if (eRet == OMX_ErrorNone) {
3065 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3066 DEBUG_PRINT_ERROR("\n Set color format failed");
3067 eRet = OMX_ErrorBadParameter;
3068 }
3069 }
3070 }
3071 }
3072 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003073
Arun Menon906de572013-06-18 17:01:40 -07003074 case OMX_QcomIndexPortDefn: {
3075 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3076 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
3077 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
3078 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003079
Arun Menon906de572013-06-18 17:01:40 -07003080 /* Input port */
3081 if (portFmt->nPortIndex == 0) {
3082 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3083 if (secure_mode) {
3084 arbitrary_bytes = false;
3085 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3086 eRet = OMX_ErrorUnsupportedSetting;
3087 } else {
3088 arbitrary_bytes = true;
3089 }
3090 } else if (portFmt->nFramePackingFormat ==
3091 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3092 arbitrary_bytes = false;
3093 } else {
3094 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
3095 portFmt->nFramePackingFormat);
3096 eRet = OMX_ErrorUnsupportedSetting;
3097 }
3098 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3099 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3100 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3101 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3102 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3103 m_out_mem_region_smi = OMX_TRUE;
3104 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3105 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3106 m_use_output_pmem = OMX_TRUE;
3107 }
3108 }
3109 }
3110 }
3111 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003112
Arun Menon906de572013-06-18 17:01:40 -07003113 case OMX_IndexParamStandardComponentRole: {
3114 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3115 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3116 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3117 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003118
Arun Menon906de572013-06-18 17:01:40 -07003119 if ((m_state == OMX_StateLoaded)&&
3120 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3121 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3122 } else {
3123 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3124 return OMX_ErrorIncorrectStateOperation;
3125 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003126
Arun Menon906de572013-06-18 17:01:40 -07003127 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3128 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3129 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3130 } else {
3131 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3132 eRet =OMX_ErrorUnsupportedSetting;
3133 }
3134 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3135 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3136 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3137 } else {
3138 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3139 eRet = OMX_ErrorUnsupportedSetting;
3140 }
3141 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3142 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3143 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3144 } else {
3145 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3146 eRet =OMX_ErrorUnsupportedSetting;
3147 }
3148 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3149 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3150 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3151 } else {
3152 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3153 eRet = OMX_ErrorUnsupportedSetting;
3154 }
3155 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3156 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3157 ) {
3158 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3159 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3160 } else {
3161 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3162 eRet =OMX_ErrorUnsupportedSetting;
3163 }
3164 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3165 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3166 ) {
3167 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3168 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3169 } else {
3170 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3171 eRet =OMX_ErrorUnsupportedSetting;
3172 }
3173 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3174 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3175 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3176 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3177 } else {
3178 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3179 eRet = OMX_ErrorUnsupportedSetting;
3180 }
3181 } else {
3182 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3183 eRet = OMX_ErrorInvalidComponentName;
3184 }
3185 break;
3186 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003187
Arun Menon906de572013-06-18 17:01:40 -07003188 case OMX_IndexParamPriorityMgmt: {
3189 if (m_state != OMX_StateLoaded) {
3190 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3191 return OMX_ErrorIncorrectStateOperation;
3192 }
3193 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
3194 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
3195 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003196
Arun Menon906de572013-06-18 17:01:40 -07003197 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
3198 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003199
Arun Menon906de572013-06-18 17:01:40 -07003200 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3201 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003202
Arun Menon906de572013-06-18 17:01:40 -07003203 break;
3204 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003205
Arun Menon906de572013-06-18 17:01:40 -07003206 case OMX_IndexParamCompBufferSupplier: {
3207 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3208 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3209 bufferSupplierType->eBufferSupplier);
3210 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3211 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003212
Arun Menon906de572013-06-18 17:01:40 -07003213 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003214
Arun Menon906de572013-06-18 17:01:40 -07003215 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003216
Arun Menon906de572013-06-18 17:01:40 -07003217 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003218
Arun Menon906de572013-06-18 17:01:40 -07003219 }
3220 case OMX_IndexParamVideoAvc: {
3221 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3222 paramIndex);
3223 break;
3224 }
3225 case OMX_IndexParamVideoH263: {
3226 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3227 paramIndex);
3228 break;
3229 }
3230 case OMX_IndexParamVideoMpeg4: {
3231 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3232 paramIndex);
3233 break;
3234 }
3235 case OMX_IndexParamVideoMpeg2: {
3236 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3237 paramIndex);
3238 break;
3239 }
3240 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3241 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3242 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3243 struct v4l2_control control;
3244 int pic_order,rc=0;
3245 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3246 pictureOrder->eOutputPictureOrder);
3247 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3248 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3249 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3250 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3251 time_stamp_dts.set_timestamp_reorder_mode(false);
3252 } else
3253 eRet = OMX_ErrorBadParameter;
3254 if (eRet == OMX_ErrorNone) {
3255 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3256 control.value = pic_order;
3257 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3258 if (rc) {
3259 DEBUG_PRINT_ERROR("\n Set picture order failed");
3260 eRet = OMX_ErrorUnsupportedSetting;
3261 }
3262 }
3263 break;
3264 }
3265 case OMX_QcomIndexParamConcealMBMapExtraData:
3266 if (!secure_mode)
3267 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3268 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3269 else {
3270 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3271 eRet = OMX_ErrorUnsupportedSetting;
3272 }
3273 break;
3274 case OMX_QcomIndexParamFrameInfoExtraData: {
3275 if (!secure_mode)
3276 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3277 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3278 else {
3279 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3280 eRet = OMX_ErrorUnsupportedSetting;
3281 }
3282 break;
3283 }
3284 case OMX_QcomIndexParamInterlaceExtraData:
3285 if (!secure_mode)
3286 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3287 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3288 else {
3289 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3290 eRet = OMX_ErrorUnsupportedSetting;
3291 }
3292 break;
3293 case OMX_QcomIndexParamH264TimeInfo:
3294 if (!secure_mode)
3295 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3296 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3297 else {
3298 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3299 eRet = OMX_ErrorUnsupportedSetting;
3300 }
3301 break;
3302 case OMX_QcomIndexParamVideoDivx: {
3303 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3304 }
3305 break;
3306 case OMX_QcomIndexPlatformPvt: {
3307 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3308 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3309 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3310 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3311 eRet = OMX_ErrorUnsupportedSetting;
3312 } else {
3313 m_out_pvt_entry_pmem = OMX_TRUE;
3314 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3315 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3316 m_use_output_pmem = OMX_TRUE;
3317 }
3318 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003319
Arun Menon906de572013-06-18 17:01:40 -07003320 }
3321 break;
3322 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3323 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3324 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3325 struct v4l2_control control;
3326 int rc;
3327 drv_ctx.idr_only_decoding = 1;
3328 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3329 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3330 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3331 if (rc) {
3332 DEBUG_PRINT_ERROR("\n Set picture order failed");
3333 eRet = OMX_ErrorUnsupportedSetting;
3334 } else {
3335 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3336 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3337 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3338 if (rc) {
3339 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3340 eRet = OMX_ErrorUnsupportedSetting;
3341 }
3342 /*Setting sync frame decoding on driver might change buffer
3343 * requirements so update them here*/
3344 if (get_buffer_req(&drv_ctx.ip_buf)) {
3345 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer i/p requirements");
3346 eRet = OMX_ErrorUnsupportedSetting;
3347 }
3348 if (get_buffer_req(&drv_ctx.op_buf)) {
3349 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer o/p requirements");
3350 eRet = OMX_ErrorUnsupportedSetting;
3351 }
3352 }
3353 }
3354 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003355
Arun Menon906de572013-06-18 17:01:40 -07003356 case OMX_QcomIndexParamIndexExtraDataType: {
3357 if (!secure_mode) {
3358 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3359 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3360 (extradataIndexType->bEnabled == OMX_TRUE) &&
3361 (extradataIndexType->nPortIndex == 1)) {
3362 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
3363 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003364
Arun Menon906de572013-06-18 17:01:40 -07003365 }
3366 }
3367 }
3368 break;
3369 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003370#ifndef SMOOTH_STREAMING_DISABLED
Arun Menon906de572013-06-18 17:01:40 -07003371 struct v4l2_control control;
3372 struct v4l2_format fmt;
3373 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3374 control.value = 1;
3375 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3376 if (rc < 0) {
3377 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3378 eRet = OMX_ErrorHardware;
3379 }
Arun Menonbc0922f2013-06-24 13:02:15 -07003380#else
Arun Menon906de572013-06-18 17:01:40 -07003381 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003382#endif
Arun Menon906de572013-06-18 17:01:40 -07003383 }
3384 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003385#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003386 /* Need to allow following two set_parameters even in Idle
3387 * state. This is ANDROID architecture which is not in sync
3388 * with openmax standard. */
3389 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3390 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3391 if (enableNativeBuffers) {
3392 m_enable_android_native_buffers = enableNativeBuffers->enable;
3393 }
3394 }
3395 break;
3396 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3397 eRet = use_android_native_buffer(hComp, paramData);
3398 }
3399 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003400#endif
Arun Menon906de572013-06-18 17:01:40 -07003401 case OMX_QcomIndexParamEnableTimeStampReorder: {
3402 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3403 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3404 if (reorder->bEnable == OMX_TRUE) {
3405 frm_int =0;
3406 time_stamp_dts.set_timestamp_reorder_mode(true);
3407 } else
3408 time_stamp_dts.set_timestamp_reorder_mode(false);
3409 } else {
3410 time_stamp_dts.set_timestamp_reorder_mode(false);
3411 if (reorder->bEnable == OMX_TRUE) {
3412 eRet = OMX_ErrorUnsupportedSetting;
3413 }
3414 }
3415 }
3416 break;
3417 case OMX_IndexParamVideoProfileLevelCurrent: {
3418 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3419 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3420 if (pParam) {
3421 m_profile_lvl.eProfile = pParam->eProfile;
3422 m_profile_lvl.eLevel = pParam->eLevel;
3423 }
3424 break;
Arun Menon888aa852013-05-30 11:24:42 -07003425
Arun Menon906de572013-06-18 17:01:40 -07003426 }
Arun Menonbdb80b02013-08-12 17:45:54 -07003427#ifdef META_DATA_MODE_SUPPORTED
Arun Menone5652482013-08-04 13:33:05 -07003428 case OMX_QcomIndexParamVideoMetaBufferMode:
3429 {
3430 StoreMetaDataInBuffersParams *metabuffer =
3431 (StoreMetaDataInBuffersParams *)paramData;
3432 if (!metabuffer) {
3433 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3434 eRet = OMX_ErrorBadParameter;
3435 break;
3436 }
3437 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3438 //set property dynamic buffer mode to driver.
3439 struct v4l2_control control;
3440 struct v4l2_format fmt;
3441 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3442 if (metabuffer->bStoreMetaData == true) {
3443 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3444 } else {
3445 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3446 }
3447 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3448 if (!rc) {
3449 DEBUG_PRINT_HIGH(" %s buffer mode\n",
3450 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003451 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003452 } else {
3453 DEBUG_PRINT_ERROR("Failed to %s buffer mode\n",
3454 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3455 eRet = OMX_ErrorUnsupportedSetting;
3456 }
3457 } else {
3458 DEBUG_PRINT_ERROR(
3459 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %d\n",
3460 metabuffer->nPortIndex);
3461 eRet = OMX_ErrorUnsupportedSetting;
3462 }
3463 break;
3464 }
Arun Menonbdb80b02013-08-12 17:45:54 -07003465#endif
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003466 case OMX_QcomIndexParamVideoDownScalar: {
3467 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3468 struct v4l2_control control;
3469 int rc;
3470 if (pParam) {
3471 is_down_scalar_enabled = pParam->bEnable;
3472 if (is_down_scalar_enabled) {
3473 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3474 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3475 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3476 pParam->bEnable);
3477 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3478 if (rc < 0) {
3479 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3480 eRet = OMX_ErrorUnsupportedSetting;
3481 }
3482 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3483 control.value = 1;
3484 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3485 if (rc < 0) {
3486 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3487 eRet = OMX_ErrorUnsupportedSetting;
3488 }
3489 }
3490 }
3491 break;
3492 }
Arun Menon906de572013-06-18 17:01:40 -07003493 default: {
3494 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3495 eRet = OMX_ErrorUnsupportedIndex;
3496 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003497 }
Arun Menon906de572013-06-18 17:01:40 -07003498 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003499}
3500
3501/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003502 FUNCTION
3503 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003504
Arun Menon906de572013-06-18 17:01:40 -07003505 DESCRIPTION
3506 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003507
Arun Menon906de572013-06-18 17:01:40 -07003508 PARAMETERS
3509 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003510
Arun Menon906de572013-06-18 17:01:40 -07003511 RETURN VALUE
3512 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003513
Arun Menon906de572013-06-18 17:01:40 -07003514 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003515OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003516 OMX_IN OMX_INDEXTYPE configIndex,
3517 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003518{
Arun Menon906de572013-06-18 17:01:40 -07003519 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003520
Arun Menon906de572013-06-18 17:01:40 -07003521 if (m_state == OMX_StateInvalid) {
3522 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003523 return OMX_ErrorInvalidState;
3524 }
Arun Menon906de572013-06-18 17:01:40 -07003525
3526 switch ((unsigned long)configIndex) {
3527 case OMX_QcomIndexConfigInterlaced: {
3528 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3529 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3530 if (configFmt->nPortIndex == 1) {
3531 if (configFmt->nIndex == 0) {
3532 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3533 } else if (configFmt->nIndex == 1) {
3534 configFmt->eInterlaceType =
3535 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3536 } else if (configFmt->nIndex == 2) {
3537 configFmt->eInterlaceType =
3538 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3539 } else {
3540 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3541 " NoMore Interlaced formats\n");
3542 eRet = OMX_ErrorNoMore;
3543 }
3544
3545 } else {
3546 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3547 (int)configFmt->nPortIndex);
3548 eRet = OMX_ErrorBadPortIndex;
3549 }
3550 break;
3551 }
3552 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3553 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3554 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3555 decoderinstances->nNumOfInstances = 16;
3556 /*TODO: How to handle this case */
3557 break;
3558 }
3559 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3560 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3561 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3562 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3563 h264_parser->get_frame_pack_data(configFmt);
3564 } else {
3565 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3566 }
3567 break;
3568 }
3569 case OMX_IndexConfigCommonOutputCrop: {
3570 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3571 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3572 break;
3573 }
3574 default: {
3575 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3576 eRet = OMX_ErrorBadParameter;
3577 }
3578
Shalaj Jain273b3e02012-06-22 19:08:03 -07003579 }
Arun Menon906de572013-06-18 17:01:40 -07003580
3581 return eRet;
3582}
3583
3584/* ======================================================================
3585 FUNCTION
3586 omx_vdec::SetConfig
3587
3588 DESCRIPTION
3589 OMX Set Config method implementation
3590
3591 PARAMETERS
3592 <TBD>.
3593
3594 RETURN VALUE
3595 OMX Error None if successful.
3596 ========================================================================== */
3597OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3598 OMX_IN OMX_INDEXTYPE configIndex,
3599 OMX_IN OMX_PTR configData)
3600{
3601 if (m_state == OMX_StateInvalid) {
3602 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3603 return OMX_ErrorInvalidState;
3604 }
3605
3606 OMX_ERRORTYPE ret = OMX_ErrorNone;
3607 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3608
3609 DEBUG_PRINT_LOW("\n Set Config Called");
3610
3611 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3612 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3613 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3614 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
3615 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3616 OMX_U32 extra_size;
3617 // Parsing done here for the AVC atom is definitely not generic
3618 // Currently this piece of code is working, but certainly
3619 // not tested with all .mp4 files.
3620 // Incase of failure, we might need to revisit this
3621 // for a generic piece of code.
3622
3623 // Retrieve size of NAL length field
3624 // byte #4 contains the size of NAL lenght field
3625 nal_length = (config->pData[4] & 0x03) + 1;
3626
3627 extra_size = 0;
3628 if (nal_length > 2) {
3629 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3630 extra_size = (nal_length - 2) * 2;
3631 }
3632
3633 // SPS starts from byte #6
3634 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3635 OMX_U8 *pDestBuf;
3636 m_vendor_config.nPortIndex = config->nPortIndex;
3637
3638 // minus 6 --> SPS starts from byte #6
3639 // minus 1 --> picture param set byte to be ignored from avcatom
3640 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3641 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3642 OMX_U32 len;
3643 OMX_U8 index = 0;
3644 // case where SPS+PPS is sent as part of set_config
3645 pDestBuf = m_vendor_config.pData;
3646
3647 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
3648 m_vendor_config.nPortIndex,
3649 m_vendor_config.nDataSize,
3650 m_vendor_config.pData);
3651 while (index < 2) {
3652 uint8 *psize;
3653 len = *pSrcBuf;
3654 len = len << 8;
3655 len |= *(pSrcBuf + 1);
3656 psize = (uint8 *) & len;
3657 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3658 for (unsigned int i = 0; i < nal_length; i++) {
3659 pDestBuf[i] = psize[nal_length - 1 - i];
3660 }
3661 //memcpy(pDestBuf,pSrcBuf,(len+2));
3662 pDestBuf += len + nal_length;
3663 pSrcBuf += len + 2;
3664 index++;
3665 pSrcBuf++; // skip picture param set
3666 len = 0;
3667 }
3668 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3669 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3670 m_vendor_config.nPortIndex = config->nPortIndex;
3671 m_vendor_config.nDataSize = config->nDataSize;
3672 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3673 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3674 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3675 if (m_vendor_config.pData) {
3676 free(m_vendor_config.pData);
3677 m_vendor_config.pData = NULL;
3678 m_vendor_config.nDataSize = 0;
3679 }
3680
3681 if (((*((OMX_U32 *) config->pData)) &
3682 VC1_SP_MP_START_CODE_MASK) ==
3683 VC1_SP_MP_START_CODE) {
3684 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3685 m_vendor_config.nPortIndex = config->nPortIndex;
3686 m_vendor_config.nDataSize = config->nDataSize;
3687 m_vendor_config.pData =
3688 (OMX_U8 *) malloc(config->nDataSize);
3689 memcpy(m_vendor_config.pData, config->pData,
3690 config->nDataSize);
3691 m_vc1_profile = VC1_SP_MP_RCV;
3692 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
3693 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3694 m_vendor_config.nPortIndex = config->nPortIndex;
3695 m_vendor_config.nDataSize = config->nDataSize;
3696 m_vendor_config.pData =
3697 (OMX_U8 *) malloc((config->nDataSize));
3698 memcpy(m_vendor_config.pData, config->pData,
3699 config->nDataSize);
3700 m_vc1_profile = VC1_AP;
3701 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
3702 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3703 m_vendor_config.nPortIndex = config->nPortIndex;
3704 m_vendor_config.nDataSize = config->nDataSize;
3705 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3706 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3707 m_vc1_profile = VC1_SP_MP_RCV;
3708 } else {
3709 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3710 }
3711 }
3712 return ret;
3713 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3714 struct v4l2_control temp;
3715 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3716
3717 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3718 switch (pNal->nNaluBytes) {
3719 case 0:
3720 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3721 break;
3722 case 2:
3723 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3724 break;
3725 case 4:
3726 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3727 break;
3728 default:
3729 return OMX_ErrorUnsupportedSetting;
3730 }
3731
3732 if (!arbitrary_bytes) {
3733 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3734 * with start code, so only need to notify driver in frame by frame mode */
3735 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3736 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3737 return OMX_ErrorHardware;
3738 }
3739 }
3740
3741 nal_length = pNal->nNaluBytes;
3742 m_frame_parser.init_nal_length(nal_length);
3743
3744 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
3745 return ret;
3746 } else if (configIndex == OMX_IndexVendorVideoFrameRate) {
3747 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
3748 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps);
3749
3750 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3751 if (config->bEnabled) {
3752 if ((config->nFps >> 16) > 0) {
3753 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d",
3754 config->nFps >> 16);
3755 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3756 drv_ctx.frame_rate.fps_denominator);
3757
3758 if (!drv_ctx.frame_rate.fps_numerator) {
3759 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3760 drv_ctx.frame_rate.fps_numerator = 30;
3761 }
3762
3763 if (drv_ctx.frame_rate.fps_denominator) {
3764 drv_ctx.frame_rate.fps_numerator = (int)
3765 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3766 }
3767
3768 drv_ctx.frame_rate.fps_denominator = 1;
3769 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3770 drv_ctx.frame_rate.fps_numerator;
3771
3772 struct v4l2_outputparm oparm;
3773 /*XXX: we're providing timing info as seconds per frame rather than frames
3774 * per second.*/
3775 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3776 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3777
3778 struct v4l2_streamparm sparm;
3779 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3780 sparm.parm.output = oparm;
3781 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3782 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3783 performance might be affected");
3784 ret = OMX_ErrorHardware;
3785 }
3786 client_set_fps = true;
3787 } else {
3788 DEBUG_PRINT_ERROR("Frame rate not supported.");
3789 ret = OMX_ErrorUnsupportedSetting;
3790 }
3791 } else {
3792 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3793 client_set_fps = false;
3794 }
3795 } else {
3796 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3797 (int)config->nPortIndex);
3798 ret = OMX_ErrorBadPortIndex;
3799 }
3800
3801 return ret;
3802 }
3803
3804 return OMX_ErrorNotImplemented;
3805}
3806
3807/* ======================================================================
3808 FUNCTION
3809 omx_vdec::GetExtensionIndex
3810
3811 DESCRIPTION
3812 OMX GetExtensionIndex method implementaion. <TBD>
3813
3814 PARAMETERS
3815 <TBD>.
3816
3817 RETURN VALUE
3818 OMX Error None if everything successful.
3819
3820 ========================================================================== */
3821OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3822 OMX_IN OMX_STRING paramName,
3823 OMX_OUT OMX_INDEXTYPE* indexType)
3824{
3825 if (m_state == OMX_StateInvalid) {
3826 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3827 return OMX_ErrorInvalidState;
3828 } else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3829 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3830 } else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003831 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3832 }
3833#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003834 else if (!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003835 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Arun Menon906de572013-06-18 17:01:40 -07003836 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003837 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Arun Menon906de572013-06-18 17:01:40 -07003838 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003839 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3840 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Arun Menon906de572013-06-18 17:01:40 -07003841 } else if (!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003842 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3843 }
3844#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07003845#ifdef META_DATA_MODE_SUPPORTED
Arun Menone5652482013-08-04 13:33:05 -07003846 else if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers", sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) {
3847 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
3848 }
Arun Menonbdb80b02013-08-12 17:45:54 -07003849#endif
Arun Menon906de572013-06-18 17:01:40 -07003850 else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003851 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3852 return OMX_ErrorNotImplemented;
3853 }
3854 return OMX_ErrorNone;
3855}
3856
3857/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003858 FUNCTION
3859 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07003860
Arun Menon906de572013-06-18 17:01:40 -07003861 DESCRIPTION
3862 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003863
Arun Menon906de572013-06-18 17:01:40 -07003864 PARAMETERS
3865 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003866
Arun Menon906de572013-06-18 17:01:40 -07003867 RETURN VALUE
3868 Error None if everything is successful.
3869 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003870OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003871 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003872{
Arun Menon906de572013-06-18 17:01:40 -07003873 *state = m_state;
3874 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
3875 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003876}
3877
3878/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003879 FUNCTION
3880 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07003881
Arun Menon906de572013-06-18 17:01:40 -07003882 DESCRIPTION
3883 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003884
Arun Menon906de572013-06-18 17:01:40 -07003885 PARAMETERS
3886 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003887
Arun Menon906de572013-06-18 17:01:40 -07003888 RETURN VALUE
3889 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003890
Arun Menon906de572013-06-18 17:01:40 -07003891 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003892OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003893 OMX_IN OMX_U32 port,
3894 OMX_IN OMX_HANDLETYPE peerComponent,
3895 OMX_IN OMX_U32 peerPort,
3896 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003897{
Arun Menon906de572013-06-18 17:01:40 -07003898 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3899 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003900}
3901
3902/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003903 FUNCTION
3904 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07003905
Arun Menon906de572013-06-18 17:01:40 -07003906 DESCRIPTION
3907 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07003908
Arun Menon906de572013-06-18 17:01:40 -07003909 PARAMETERS
3910 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003911
Arun Menon906de572013-06-18 17:01:40 -07003912 RETURN VALUE
3913 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07003914
Arun Menon906de572013-06-18 17:01:40 -07003915 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003916OMX_ERRORTYPE omx_vdec::allocate_extradata()
3917{
3918#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003919 if (drv_ctx.extradata_info.buffer_size) {
3920 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
3921 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3922 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3923 free_ion_memory(&drv_ctx.extradata_info.ion);
3924 }
3925 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
3926 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
3927 drv_ctx.extradata_info.size, 4096,
3928 &drv_ctx.extradata_info.ion.ion_alloc_data,
3929 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
3930 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
3931 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
3932 return OMX_ErrorInsufficientResources;
3933 }
3934 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
3935 drv_ctx.extradata_info.size,
3936 PROT_READ|PROT_WRITE, MAP_SHARED,
3937 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
3938 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
3939 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
3940 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3941 free_ion_memory(&drv_ctx.extradata_info.ion);
3942 return OMX_ErrorInsufficientResources;
3943 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003944 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003945#endif
Arun Menon906de572013-06-18 17:01:40 -07003946 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003947}
3948
Arun Menon906de572013-06-18 17:01:40 -07003949void omx_vdec::free_extradata()
3950{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003951#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003952 if (drv_ctx.extradata_info.uaddr) {
3953 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3954 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3955 free_ion_memory(&drv_ctx.extradata_info.ion);
3956 }
3957 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003958#endif
3959}
3960
Shalaj Jain273b3e02012-06-22 19:08:03 -07003961OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07003962 OMX_IN OMX_HANDLETYPE hComp,
3963 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3964 OMX_IN OMX_U32 port,
3965 OMX_IN OMX_PTR appData,
3966 OMX_IN OMX_U32 bytes,
3967 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003968{
Arun Menon906de572013-06-18 17:01:40 -07003969 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3970 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
3971 unsigned i= 0; // Temporary counter
3972 struct vdec_setbuffer_cmd setbuffers;
3973 OMX_PTR privateAppData = NULL;
3974 private_handle_t *handle = NULL;
3975 OMX_U8 *buff = buffer;
3976 struct v4l2_buffer buf;
3977 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3978 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003979
Arun Menon906de572013-06-18 17:01:40 -07003980 if (!m_out_mem_ptr) {
3981 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
3982 eRet = allocate_output_headers();
3983 if (eRet == OMX_ErrorNone)
3984 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07003985 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003986
Arun Menon906de572013-06-18 17:01:40 -07003987 if (eRet == OMX_ErrorNone) {
3988 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
3989 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
3990 break;
3991 }
3992 }
3993 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003994
Arun Menon906de572013-06-18 17:01:40 -07003995 if (i >= drv_ctx.op_buf.actualcount) {
3996 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
3997 eRet = OMX_ErrorInsufficientResources;
3998 }
3999
Arun Menonbdb80b02013-08-12 17:45:54 -07004000#ifdef META_DATA_MODE_SUPPORTED
4001 if (dynamic_buf_mode) {
4002 *bufferHdr = (m_out_mem_ptr + i );
4003 (*bufferHdr)->pBuffer = NULL;
4004 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4005 enum v4l2_buf_type buf_type;
4006 int rr = 0;
4007 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4008 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4009 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4010 return OMX_ErrorInsufficientResources;
4011 } else {
4012 streaming[CAPTURE_PORT] = true;
4013 DEBUG_PRINT_LOW("STREAMON Successful");
4014 }
4015 }
4016 BITMASK_SET(&m_out_bm_count,i);
4017 (*bufferHdr)->pAppPrivate = appData;
4018 (*bufferHdr)->pBuffer = buffer;
4019 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4020 return eRet;
4021 }
4022#endif
Arun Menon906de572013-06-18 17:01:40 -07004023 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004024#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004025 if (m_enable_android_native_buffers) {
4026 if (m_use_android_native_buffers) {
4027 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4028 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4029 handle = (private_handle_t *)nBuf->handle;
4030 privateAppData = params->pAppPrivate;
4031 } else {
4032 handle = (private_handle_t *)buff;
4033 privateAppData = appData;
4034 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004035
Arun Menon906de572013-06-18 17:01:40 -07004036 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4037 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4038 " expected %u, got %lu",
4039 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4040 return OMX_ErrorBadParameter;
4041 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004042
Arun Menon906de572013-06-18 17:01:40 -07004043 if (!m_use_android_native_buffers) {
4044 if (!secure_mode) {
4045 buff = (OMX_U8*)mmap(0, handle->size,
4046 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4047 if (buff == MAP_FAILED) {
4048 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4049 return OMX_ErrorInsufficientResources;
4050 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004051 }
4052 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004053#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004054 native_buffer[i].nativehandle = handle;
4055 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004056#endif
Arun Menon906de572013-06-18 17:01:40 -07004057 if (!handle) {
4058 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4059 return OMX_ErrorBadParameter;
4060 }
4061 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4062 drv_ctx.ptr_outputbuffer[i].offset = 0;
4063 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4064 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4065 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4066 } else
4067#endif
4068
4069 if (!ouput_egl_buffers && !m_use_output_pmem) {
4070#ifdef USE_ION
4071 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4072 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4073 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4074 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4075 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
4076 DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd);
4077 return OMX_ErrorInsufficientResources;
4078 }
4079 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4080 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4081#else
4082 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4083 open (MEM_DEVICE,O_RDWR);
4084
4085 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
4086 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
4087 return OMX_ErrorInsufficientResources;
4088 }
4089
4090 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4091 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4092 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4093 open (MEM_DEVICE,O_RDWR);
4094 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
4095 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
4096 return OMX_ErrorInsufficientResources;
4097 }
4098 }
4099
4100 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4101 drv_ctx.op_buf.buffer_size,
4102 drv_ctx.op_buf.alignment)) {
4103 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4104 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4105 return OMX_ErrorInsufficientResources;
4106 }
4107#endif
4108 if (!secure_mode) {
4109 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4110 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4111 PROT_READ|PROT_WRITE, MAP_SHARED,
4112 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4113 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4114 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4115#ifdef USE_ION
4116 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4117#endif
4118 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
4119 return OMX_ErrorInsufficientResources;
4120 }
4121 }
4122 drv_ctx.ptr_outputbuffer[i].offset = 0;
4123 privateAppData = appData;
4124 } else {
4125
4126 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4127 if (!appData || !bytes ) {
4128 if (!secure_mode && !buffer) {
4129 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4130 return OMX_ErrorBadParameter;
4131 }
4132 }
4133
4134 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4135 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4136 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4137 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4138 !pmem_list->nEntries ||
4139 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4140 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4141 return OMX_ErrorBadParameter;
4142 }
4143 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4144 pmem_list->entryList->entry;
4145 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4146 pmem_info->pmem_fd);
4147 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4148 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4149 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4150 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4151 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4152 privateAppData = appData;
4153 }
4154 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4155 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4156
4157 *bufferHdr = (m_out_mem_ptr + i );
4158 if (secure_mode)
4159 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4160 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4161 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4162 sizeof (vdec_bufferpayload));
4163
4164 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4165 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4166 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4167
4168 buf.index = i;
4169 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4170 buf.memory = V4L2_MEMORY_USERPTR;
4171 plane[0].length = drv_ctx.op_buf.buffer_size;
4172 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4173 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4174 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4175 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4176 plane[0].data_offset = 0;
4177 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4178 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4179 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4180 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4181#ifdef USE_ION
4182 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4183#endif
4184 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4185 plane[extra_idx].data_offset = 0;
4186 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4187 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004188 return OMX_ErrorBadParameter;
4189 }
Arun Menon906de572013-06-18 17:01:40 -07004190 buf.m.planes = plane;
4191 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004192
Arun Menon906de572013-06-18 17:01:40 -07004193 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4194 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4195 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004196 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004197 }
4198
Arun Menon906de572013-06-18 17:01:40 -07004199 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4200 enum v4l2_buf_type buf_type;
4201 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4202 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4203 return OMX_ErrorInsufficientResources;
4204 } else {
4205 streaming[CAPTURE_PORT] = true;
4206 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004207 }
4208 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004209
Arun Menon906de572013-06-18 17:01:40 -07004210 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4211 if (m_enable_android_native_buffers) {
4212 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4213 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4214 } else {
4215 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004216 }
Arun Menon906de572013-06-18 17:01:40 -07004217 (*bufferHdr)->pAppPrivate = privateAppData;
4218 BITMASK_SET(&m_out_bm_count,i);
4219 }
4220 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004221}
4222
4223/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004224 FUNCTION
4225 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004226
Arun Menon906de572013-06-18 17:01:40 -07004227 DESCRIPTION
4228 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004229
Arun Menon906de572013-06-18 17:01:40 -07004230 PARAMETERS
4231 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004232
Arun Menon906de572013-06-18 17:01:40 -07004233 RETURN VALUE
4234 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004235
Arun Menon906de572013-06-18 17:01:40 -07004236 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004237OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004238 OMX_IN OMX_HANDLETYPE hComp,
4239 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4240 OMX_IN OMX_U32 port,
4241 OMX_IN OMX_PTR appData,
4242 OMX_IN OMX_U32 bytes,
4243 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004244{
Arun Menon906de572013-06-18 17:01:40 -07004245 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4246 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4247 if (!m_inp_heap_ptr)
4248 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4249 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4250 drv_ctx.ip_buf.actualcount);
4251 if (!m_phdr_pmem_ptr)
4252 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4253 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4254 drv_ctx.ip_buf.actualcount);
4255 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4256 DEBUG_PRINT_ERROR("Insufficent memory");
4257 eRet = OMX_ErrorInsufficientResources;
4258 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4259 input_use_buffer = true;
4260 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4261 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4262 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4263 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4264 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4265 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4266 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4267 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4268 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
4269 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4270 (unsigned)NULL, (unsigned)NULL)) {
4271 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4272 return OMX_ErrorInsufficientResources;
4273 }
4274 m_in_alloc_cnt++;
4275 } else {
4276 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4277 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004278 }
Arun Menon906de572013-06-18 17:01:40 -07004279 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004280}
4281
4282/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004283 FUNCTION
4284 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004285
Arun Menon906de572013-06-18 17:01:40 -07004286 DESCRIPTION
4287 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004288
Arun Menon906de572013-06-18 17:01:40 -07004289 PARAMETERS
4290 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004291
Arun Menon906de572013-06-18 17:01:40 -07004292 RETURN VALUE
4293 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004294
Arun Menon906de572013-06-18 17:01:40 -07004295 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004296OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004297 OMX_IN OMX_HANDLETYPE hComp,
4298 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4299 OMX_IN OMX_U32 port,
4300 OMX_IN OMX_PTR appData,
4301 OMX_IN OMX_U32 bytes,
4302 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004303{
Arun Menon906de572013-06-18 17:01:40 -07004304 OMX_ERRORTYPE error = OMX_ErrorNone;
4305 struct vdec_setbuffer_cmd setbuffers;
4306
4307 if (bufferHdr == NULL || bytes == 0) {
4308 if (!secure_mode && buffer == NULL) {
4309 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4310 return OMX_ErrorBadParameter;
4311 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004312 }
Arun Menon906de572013-06-18 17:01:40 -07004313 if (m_state == OMX_StateInvalid) {
4314 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4315 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004316 }
Arun Menon906de572013-06-18 17:01:40 -07004317 if (port == OMX_CORE_INPUT_PORT_INDEX)
4318 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4319 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4320 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4321 else {
4322 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4323 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004324 }
Arun Menon906de572013-06-18 17:01:40 -07004325 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4326 if (error == OMX_ErrorNone) {
4327 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4328 // Send the callback now
4329 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4330 post_event(OMX_CommandStateSet,OMX_StateIdle,
4331 OMX_COMPONENT_GENERATE_EVENT);
4332 }
4333 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4334 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4335 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4336 post_event(OMX_CommandPortEnable,
4337 OMX_CORE_INPUT_PORT_INDEX,
4338 OMX_COMPONENT_GENERATE_EVENT);
4339 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4340 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4341 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4342 post_event(OMX_CommandPortEnable,
4343 OMX_CORE_OUTPUT_PORT_INDEX,
4344 OMX_COMPONENT_GENERATE_EVENT);
4345 }
4346 }
4347 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004348}
4349
4350OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004351 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004352{
Arun Menon906de572013-06-18 17:01:40 -07004353 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4354 if (m_inp_heap_ptr[bufferindex].pBuffer)
4355 free(m_inp_heap_ptr[bufferindex].pBuffer);
4356 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4357 }
4358 if (pmem_bufferHdr)
4359 free_input_buffer(pmem_bufferHdr);
4360 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004361}
4362
4363OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4364{
Arun Menon906de572013-06-18 17:01:40 -07004365 unsigned int index = 0;
4366 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4367 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004368 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004369
Arun Menon906de572013-06-18 17:01:40 -07004370 index = bufferHdr - m_inp_mem_ptr;
4371 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4372
4373 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
4374 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4375 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4376 struct vdec_setbuffer_cmd setbuffers;
4377 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4378 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4379 sizeof (vdec_bufferpayload));
4380 if (!secure_mode) {
4381 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4382 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4383 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4384 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4385 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4386 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4387 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4388 }
4389 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4390 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4391 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4392 free(m_desc_buffer_ptr[index].buf_addr);
4393 m_desc_buffer_ptr[index].buf_addr = NULL;
4394 m_desc_buffer_ptr[index].desc_data_size = 0;
4395 }
4396#ifdef USE_ION
4397 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4398#endif
4399 }
4400 }
4401
4402 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004403}
4404
4405OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4406{
Arun Menon906de572013-06-18 17:01:40 -07004407 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004408
Arun Menon906de572013-06-18 17:01:40 -07004409 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4410 return OMX_ErrorBadParameter;
4411 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004412
Arun Menon906de572013-06-18 17:01:40 -07004413 index = bufferHdr - m_out_mem_ptr;
4414 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004415
Arun Menon906de572013-06-18 17:01:40 -07004416 if (index < drv_ctx.op_buf.actualcount
4417 && drv_ctx.ptr_outputbuffer) {
4418 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
4419 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004420
Arun Menon906de572013-06-18 17:01:40 -07004421 struct vdec_setbuffer_cmd setbuffers;
4422 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4423 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4424 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004425#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004426 if (m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004427 if (!secure_mode) {
Arun Menon906de572013-06-18 17:01:40 -07004428 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4429 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4430 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4431 }
Praveen Chavan212671f2013-04-05 20:00:42 -07004432 }
Arun Menon906de572013-06-18 17:01:40 -07004433 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4434 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004435#endif
Arun Menon906de572013-06-18 17:01:40 -07004436 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4437 if (!secure_mode) {
4438 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4439 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4440 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4441 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4442 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4443 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4444 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4445 }
4446 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4447 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004448#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004449 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004450#endif
Arun Menon906de572013-06-18 17:01:40 -07004451 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004452#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004453 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004454#endif
Arun Menon906de572013-06-18 17:01:40 -07004455 if (release_output_done()) {
4456 free_extradata();
4457 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004458 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004459
Arun Menon906de572013-06-18 17:01:40 -07004460 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004461
4462}
4463
4464OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004465 OMX_BUFFERHEADERTYPE **bufferHdr,
4466 OMX_U32 port,
4467 OMX_PTR appData,
4468 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004469{
Arun Menon906de572013-06-18 17:01:40 -07004470 OMX_BUFFERHEADERTYPE *input = NULL;
4471 unsigned char *buf_addr = NULL;
4472 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4473 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004474
Arun Menon906de572013-06-18 17:01:40 -07004475 /* Sanity Check*/
4476 if (bufferHdr == NULL) {
4477 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004478 }
4479
Arun Menon906de572013-06-18 17:01:40 -07004480 if (m_inp_heap_ptr == NULL) {
4481 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4482 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4483 drv_ctx.ip_buf.actualcount);
4484 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4485 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4486 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004487
Arun Menon906de572013-06-18 17:01:40 -07004488 if (m_inp_heap_ptr == NULL) {
4489 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4490 return OMX_ErrorInsufficientResources;
4491 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004492 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004493
Arun Menon906de572013-06-18 17:01:40 -07004494 /*Find a Free index*/
4495 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4496 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
4497 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4498 break;
4499 }
4500 }
4501
4502 if (i < drv_ctx.ip_buf.actualcount) {
4503 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4504
4505 if (buf_addr == NULL) {
4506 return OMX_ErrorInsufficientResources;
4507 }
4508
4509 *bufferHdr = (m_inp_heap_ptr + i);
4510 input = *bufferHdr;
4511 BITMASK_SET(&m_heap_inp_bm_count,i);
4512
4513 input->pBuffer = (OMX_U8 *)buf_addr;
4514 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4515 input->nVersion.nVersion = OMX_SPEC_VERSION;
4516 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4517 input->pAppPrivate = appData;
4518 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4519 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4520 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4521 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
4522 /*Add the Buffers to freeq*/
4523 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4524 (unsigned)NULL, (unsigned)NULL)) {
4525 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4526 return OMX_ErrorInsufficientResources;
4527 }
4528 } else {
4529 return OMX_ErrorBadParameter;
4530 }
4531
4532 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004533
4534}
4535
4536
4537/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004538 FUNCTION
4539 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004540
Arun Menon906de572013-06-18 17:01:40 -07004541 DESCRIPTION
4542 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004543
Arun Menon906de572013-06-18 17:01:40 -07004544 PARAMETERS
4545 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004546
Arun Menon906de572013-06-18 17:01:40 -07004547 RETURN VALUE
4548 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004549
Arun Menon906de572013-06-18 17:01:40 -07004550 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004551OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004552 OMX_IN OMX_HANDLETYPE hComp,
4553 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4554 OMX_IN OMX_U32 port,
4555 OMX_IN OMX_PTR appData,
4556 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004557{
4558
Arun Menon906de572013-06-18 17:01:40 -07004559 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4560 struct vdec_setbuffer_cmd setbuffers;
4561 OMX_BUFFERHEADERTYPE *input = NULL;
4562 unsigned i = 0;
4563 unsigned char *buf_addr = NULL;
4564 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004565
Arun Menon906de572013-06-18 17:01:40 -07004566 if (bytes != drv_ctx.ip_buf.buffer_size) {
4567 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
4568 bytes, drv_ctx.ip_buf.buffer_size);
4569 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004570 }
4571
Arun Menon906de572013-06-18 17:01:40 -07004572 if (!m_inp_mem_ptr) {
4573 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4574 drv_ctx.ip_buf.actualcount,
4575 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004576
Arun Menon906de572013-06-18 17:01:40 -07004577 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4578 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4579
4580 if (m_inp_mem_ptr == NULL) {
4581 return OMX_ErrorInsufficientResources;
4582 }
4583
4584 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4585 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4586
4587 if (drv_ctx.ptr_inputbuffer == NULL) {
4588 return OMX_ErrorInsufficientResources;
4589 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004590#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004591 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4592 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004593
Arun Menon906de572013-06-18 17:01:40 -07004594 if (drv_ctx.ip_buf_ion_info == NULL) {
4595 return OMX_ErrorInsufficientResources;
4596 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004597#endif
4598
Arun Menon906de572013-06-18 17:01:40 -07004599 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4600 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004601#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004602 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004603#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004604 }
4605 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004606
Arun Menon906de572013-06-18 17:01:40 -07004607 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4608 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4609 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4610 break;
4611 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004612 }
Arun Menon906de572013-06-18 17:01:40 -07004613
4614 if (i < drv_ctx.ip_buf.actualcount) {
4615 struct v4l2_buffer buf;
4616 struct v4l2_plane plane;
4617 int rc;
4618 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4619#ifdef USE_ION
4620 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4621 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4622 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4623 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4624 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4625 return OMX_ErrorInsufficientResources;
4626 }
4627 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4628#else
4629 pmem_fd = open (MEM_DEVICE,O_RDWR);
4630
4631 if (pmem_fd < 0) {
4632 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4633 return OMX_ErrorInsufficientResources;
4634 }
4635
4636 if (pmem_fd == 0) {
4637 pmem_fd = open (MEM_DEVICE,O_RDWR);
4638
4639 if (pmem_fd < 0) {
4640 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4641 return OMX_ErrorInsufficientResources;
4642 }
4643 }
4644
4645 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4646 drv_ctx.ip_buf.alignment)) {
4647 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4648 close(pmem_fd);
4649 return OMX_ErrorInsufficientResources;
4650 }
4651#endif
4652 if (!secure_mode) {
4653 buf_addr = (unsigned char *)mmap(NULL,
4654 drv_ctx.ip_buf.buffer_size,
4655 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4656
4657 if (buf_addr == MAP_FAILED) {
4658 close(pmem_fd);
4659#ifdef USE_ION
4660 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4661#endif
4662 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4663 return OMX_ErrorInsufficientResources;
4664 }
4665 }
4666 *bufferHdr = (m_inp_mem_ptr + i);
4667 if (secure_mode)
4668 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4669 else
4670 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4671 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4672 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4673 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4674 drv_ctx.ptr_inputbuffer [i].offset = 0;
4675
4676
4677 buf.index = i;
4678 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4679 buf.memory = V4L2_MEMORY_USERPTR;
4680 plane.bytesused = 0;
4681 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4682 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4683 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4684 plane.reserved[1] = 0;
4685 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4686 buf.m.planes = &plane;
4687 buf.length = 1;
4688
4689 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4690 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4691
4692 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4693
4694 if (rc) {
4695 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4696 /*TODO: How to handle this case */
4697 return OMX_ErrorInsufficientResources;
4698 }
4699
4700 input = *bufferHdr;
4701 BITMASK_SET(&m_inp_bm_count,i);
4702 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4703 if (secure_mode)
4704 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4705 else
4706 input->pBuffer = (OMX_U8 *)buf_addr;
4707 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4708 input->nVersion.nVersion = OMX_SPEC_VERSION;
4709 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4710 input->pAppPrivate = appData;
4711 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4712 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4713
4714 if (drv_ctx.disable_dmx) {
4715 eRet = allocate_desc_buffer(i);
4716 }
4717 } else {
4718 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4719 eRet = OMX_ErrorInsufficientResources;
4720 }
4721 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004722}
4723
4724
4725/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004726 FUNCTION
4727 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004728
Arun Menon906de572013-06-18 17:01:40 -07004729 DESCRIPTION
4730 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004731
Arun Menon906de572013-06-18 17:01:40 -07004732 PARAMETERS
4733 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004734
Arun Menon906de572013-06-18 17:01:40 -07004735 RETURN VALUE
4736 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004737
Arun Menon906de572013-06-18 17:01:40 -07004738 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004739OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004740 OMX_IN OMX_HANDLETYPE hComp,
4741 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4742 OMX_IN OMX_U32 port,
4743 OMX_IN OMX_PTR appData,
4744 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004745{
Arun Menon906de572013-06-18 17:01:40 -07004746 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4747 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4748 unsigned i= 0; // Temporary counter
4749 struct vdec_setbuffer_cmd setbuffers;
4750 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004751#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004752 int ion_device_fd =-1;
4753 struct ion_allocation_data ion_alloc_data;
4754 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004755#endif
Arun Menon906de572013-06-18 17:01:40 -07004756 if (!m_out_mem_ptr) {
4757 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4758 drv_ctx.op_buf.actualcount,
4759 drv_ctx.op_buf.buffer_size);
4760 int nBufHdrSize = 0;
4761 int nPlatformEntrySize = 0;
4762 int nPlatformListSize = 0;
4763 int nPMEMInfoSize = 0;
4764 int pmem_fd = -1;
4765 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004766
Arun Menon906de572013-06-18 17:01:40 -07004767 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4768 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4769 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004770
Arun Menon906de572013-06-18 17:01:40 -07004771 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4772 drv_ctx.op_buf.actualcount);
4773 nBufHdrSize = drv_ctx.op_buf.actualcount *
4774 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004775
Arun Menon906de572013-06-18 17:01:40 -07004776 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4777 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4778 nPlatformListSize = drv_ctx.op_buf.actualcount *
4779 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4780 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4781 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004782
Arun Menon906de572013-06-18 17:01:40 -07004783 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4784 sizeof(OMX_BUFFERHEADERTYPE),
4785 nPMEMInfoSize,
4786 nPlatformListSize);
4787 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4788 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004789#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004790 ion_device_fd = alloc_map_ion_memory(
4791 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4792 drv_ctx.op_buf.alignment,
4793 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4794 if (ion_device_fd < 0) {
4795 return OMX_ErrorInsufficientResources;
4796 }
4797 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004798#else
Arun Menon906de572013-06-18 17:01:40 -07004799 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004800
Arun Menon906de572013-06-18 17:01:40 -07004801 if (pmem_fd < 0) {
4802 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4803 drv_ctx.op_buf.buffer_size);
4804 return OMX_ErrorInsufficientResources;
4805 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004806
Arun Menon906de572013-06-18 17:01:40 -07004807 if (pmem_fd == 0) {
4808 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004809
Arun Menon906de572013-06-18 17:01:40 -07004810 if (pmem_fd < 0) {
4811 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4812 drv_ctx.op_buf.buffer_size);
4813 return OMX_ErrorInsufficientResources;
4814 }
4815 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004816
Arun Menon906de572013-06-18 17:01:40 -07004817 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4818 drv_ctx.op_buf.actualcount,
4819 drv_ctx.op_buf.alignment)) {
4820 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4821 close(pmem_fd);
4822 return OMX_ErrorInsufficientResources;
4823 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004824#endif
Arun Menon906de572013-06-18 17:01:40 -07004825 if (!secure_mode) {
4826 pmem_baseaddress = (unsigned char *)mmap(NULL,
4827 (drv_ctx.op_buf.buffer_size *
4828 drv_ctx.op_buf.actualcount),
4829 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4830 if (pmem_baseaddress == MAP_FAILED) {
4831 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4832 drv_ctx.op_buf.buffer_size);
4833 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004834#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004835 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004836#endif
Arun Menon906de572013-06-18 17:01:40 -07004837 return OMX_ErrorInsufficientResources;
4838 }
4839 }
4840 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4841 // Alloc mem for platform specific info
4842 char *pPtr=NULL;
4843 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4844 nPMEMInfoSize,1);
4845 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4846 calloc (sizeof(struct vdec_bufferpayload),
4847 drv_ctx.op_buf.actualcount);
4848 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4849 calloc (sizeof (struct vdec_output_frameinfo),
4850 drv_ctx.op_buf.actualcount);
4851#ifdef USE_ION
4852 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4853 calloc (sizeof(struct vdec_ion),
4854 drv_ctx.op_buf.actualcount);
4855#endif
4856
4857 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4858 && drv_ctx.ptr_respbuffer) {
4859 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4860 (drv_ctx.op_buf.buffer_size *
4861 drv_ctx.op_buf.actualcount);
4862 bufHdr = m_out_mem_ptr;
4863 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4864 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4865 (((char *) m_platform_list) + nPlatformListSize);
4866 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4867 (((char *) m_platform_entry) + nPlatformEntrySize);
4868 pPlatformList = m_platform_list;
4869 pPlatformEntry = m_platform_entry;
4870 pPMEMInfo = m_pmem_info;
4871
4872 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
4873
4874 // Settting the entire storage nicely
4875 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
4876 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
4877 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4878 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4879 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4880 // Set the values when we determine the right HxW param
4881 bufHdr->nAllocLen = bytes;
4882 bufHdr->nFilledLen = 0;
4883 bufHdr->pAppPrivate = appData;
4884 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4885 // Platform specific PMEM Information
4886 // Initialize the Platform Entry
4887 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
4888 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4889 pPlatformEntry->entry = pPMEMInfo;
4890 // Initialize the Platform List
4891 pPlatformList->nEntries = 1;
4892 pPlatformList->entryList = pPlatformEntry;
4893 // Keep pBuffer NULL till vdec is opened
4894 bufHdr->pBuffer = NULL;
4895 bufHdr->nOffset = 0;
4896
4897 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4898 pPMEMInfo->pmem_fd = 0;
4899 bufHdr->pPlatformPrivate = pPlatformList;
4900
4901 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
4902 m_pmem_info[i].pmem_fd = pmem_fd;
4903#ifdef USE_ION
4904 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
4905 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
4906 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
4907#endif
4908
4909 /*Create a mapping between buffers*/
4910 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
4911 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
4912 &drv_ctx.ptr_outputbuffer[i];
4913 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
4914 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4915 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
4916
4917 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
4918 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
4919 drv_ctx.ptr_outputbuffer[i].bufferaddr);
4920 // Move the buffer and buffer header pointers
4921 bufHdr++;
4922 pPMEMInfo++;
4923 pPlatformEntry++;
4924 pPlatformList++;
4925 }
4926 } else {
4927 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
4928 m_out_mem_ptr, pPtr);
4929 if (m_out_mem_ptr) {
4930 free(m_out_mem_ptr);
4931 m_out_mem_ptr = NULL;
4932 }
4933 if (pPtr) {
4934 free(pPtr);
4935 pPtr = NULL;
4936 }
4937 if (drv_ctx.ptr_outputbuffer) {
4938 free(drv_ctx.ptr_outputbuffer);
4939 drv_ctx.ptr_outputbuffer = NULL;
4940 }
4941 if (drv_ctx.ptr_respbuffer) {
4942 free(drv_ctx.ptr_respbuffer);
4943 drv_ctx.ptr_respbuffer = NULL;
4944 }
4945#ifdef USE_ION
4946 if (drv_ctx.op_buf_ion_info) {
4947 DEBUG_PRINT_LOW("\n Free o/p ion context");
4948 free(drv_ctx.op_buf_ion_info);
4949 drv_ctx.op_buf_ion_info = NULL;
4950 }
4951#endif
4952 eRet = OMX_ErrorInsufficientResources;
4953 }
4954 if (eRet == OMX_ErrorNone)
4955 eRet = allocate_extradata();
4956 }
4957
4958 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4959 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4960 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
4961 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004962 }
4963 }
Arun Menon906de572013-06-18 17:01:40 -07004964
4965 if (eRet == OMX_ErrorNone) {
4966 if (i < drv_ctx.op_buf.actualcount) {
4967 struct v4l2_buffer buf;
4968 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4969 int rc;
4970 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4971
4972 drv_ctx.ptr_outputbuffer[i].buffer_len =
4973 drv_ctx.op_buf.buffer_size;
4974
4975 *bufferHdr = (m_out_mem_ptr + i );
4976 if (secure_mode) {
4977 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4978 }
4979 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
4980
4981 buf.index = i;
4982 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4983 buf.memory = V4L2_MEMORY_USERPTR;
4984 plane[0].length = drv_ctx.op_buf.buffer_size;
4985 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4986 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004987#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004988 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004989#endif
Arun Menon906de572013-06-18 17:01:40 -07004990 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4991 plane[0].data_offset = 0;
4992 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4993 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4994 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4995 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 -07004996#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004997 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004998#endif
Arun Menon906de572013-06-18 17:01:40 -07004999 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5000 plane[extra_idx].data_offset = 0;
5001 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5002 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5003 return OMX_ErrorBadParameter;
5004 }
5005 buf.m.planes = plane;
5006 buf.length = drv_ctx.num_planes;
5007 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
5008 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5009 if (rc) {
5010 /*TODO: How to handle this case */
5011 return OMX_ErrorInsufficientResources;
5012 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005013
Arun Menon906de572013-06-18 17:01:40 -07005014 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5015 enum v4l2_buf_type buf_type;
5016 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5017 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5018 if (rc) {
5019 return OMX_ErrorInsufficientResources;
5020 } else {
5021 streaming[CAPTURE_PORT] = true;
5022 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5023 }
5024 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005025
Arun Menon906de572013-06-18 17:01:40 -07005026 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5027 (*bufferHdr)->pAppPrivate = appData;
5028 BITMASK_SET(&m_out_bm_count,i);
5029 } else {
5030 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5031 eRet = OMX_ErrorInsufficientResources;
5032 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005033 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005034
Arun Menon906de572013-06-18 17:01:40 -07005035 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005036}
5037
5038
5039// AllocateBuffer -- API Call
5040/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005041 FUNCTION
5042 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005043
Arun Menon906de572013-06-18 17:01:40 -07005044 DESCRIPTION
5045 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005046
Arun Menon906de572013-06-18 17:01:40 -07005047 PARAMETERS
5048 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005049
Arun Menon906de572013-06-18 17:01:40 -07005050 RETURN VALUE
5051 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005052
Arun Menon906de572013-06-18 17:01:40 -07005053 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005054OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005055 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5056 OMX_IN OMX_U32 port,
5057 OMX_IN OMX_PTR appData,
5058 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005059{
5060 unsigned i = 0;
5061 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5062
5063 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005064 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005065 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5066 return OMX_ErrorInvalidState;
5067 }
5068
Arun Menon906de572013-06-18 17:01:40 -07005069 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5070 if (arbitrary_bytes) {
5071 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5072 } else {
5073 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5074 }
5075 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005076 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5077 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005078 } else {
5079 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5080 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005081 }
5082 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005083 if (eRet == OMX_ErrorNone) {
5084 if (allocate_done()) {
5085 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005086 // Send the callback now
5087 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5088 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005089 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005090 }
5091 }
Arun Menon906de572013-06-18 17:01:40 -07005092 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5093 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5094 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5095 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005096 OMX_CORE_INPUT_PORT_INDEX,
5097 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005098 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005099 }
Arun Menon906de572013-06-18 17:01:40 -07005100 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5101 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5102 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005103 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005104 OMX_CORE_OUTPUT_PORT_INDEX,
5105 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005106 }
5107 }
5108 }
5109 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5110 return eRet;
5111}
5112
5113// Free Buffer - API call
5114/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005115 FUNCTION
5116 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005117
Arun Menon906de572013-06-18 17:01:40 -07005118 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005119
Arun Menon906de572013-06-18 17:01:40 -07005120 PARAMETERS
5121 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005122
Arun Menon906de572013-06-18 17:01:40 -07005123 RETURN VALUE
5124 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005125
Arun Menon906de572013-06-18 17:01:40 -07005126 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005127OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005128 OMX_IN OMX_U32 port,
5129 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005130{
5131 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5132 unsigned int nPortIndex;
5133 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5134
Arun Menon906de572013-06-18 17:01:40 -07005135 if (m_state == OMX_StateIdle &&
5136 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005137 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
Arun Menon906de572013-06-18 17:01:40 -07005138 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5139 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005140 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Arun Menon906de572013-06-18 17:01:40 -07005141 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5142 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5143 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5144 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Arun Menon9f098152013-05-08 13:53:54 -07005145 DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port);
Arun Menon906de572013-06-18 17:01:40 -07005146 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005147 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5148 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005149 OMX_ErrorPortUnpopulated,
5150 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005151
5152 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005153 } else if (m_state != OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005154 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5155 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005156 OMX_ErrorPortUnpopulated,
5157 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005158 }
5159
Arun Menon906de572013-06-18 17:01:40 -07005160 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5161 /*Check if arbitrary bytes*/
5162 if (!arbitrary_bytes && !input_use_buffer)
5163 nPortIndex = buffer - m_inp_mem_ptr;
5164 else
5165 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005166
5167 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005168 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5169 // Clear the bit associated with it.
5170 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5171 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5172 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005173
Arun Menon906de572013-06-18 17:01:40 -07005174 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5175 if (m_phdr_pmem_ptr)
5176 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5177 } else {
5178 if (arbitrary_bytes) {
5179 if (m_phdr_pmem_ptr)
5180 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5181 else
5182 free_input_buffer(nPortIndex,NULL);
5183 } else
5184 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005185 }
Arun Menon906de572013-06-18 17:01:40 -07005186 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305187 if(release_input_done())
5188 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005189 /*Free the Buffer Header*/
5190 if (release_input_done()) {
5191 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5192 free_input_buffer_header();
5193 }
5194 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005195 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5196 eRet = OMX_ErrorBadPortIndex;
5197 }
5198
Arun Menon906de572013-06-18 17:01:40 -07005199 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5200 && release_input_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005201 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5202 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5203 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005204 OMX_CORE_INPUT_PORT_INDEX,
5205 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005206 }
Arun Menon906de572013-06-18 17:01:40 -07005207 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005208 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005209 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005210 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005211 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5212 // Clear the bit associated with it.
5213 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5214 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005215 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005216
Surajit Podder12aefac2013-08-06 18:43:32 +05305217 if(release_output_done()) {
5218 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5219 }
Arun Menon906de572013-06-18 17:01:40 -07005220 if (release_output_done()) {
5221 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005222 }
Arun Menon906de572013-06-18 17:01:40 -07005223 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005224 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5225 eRet = OMX_ErrorBadPortIndex;
5226 }
Arun Menon906de572013-06-18 17:01:40 -07005227 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5228 && release_output_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005229 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5230
Arun Menon906de572013-06-18 17:01:40 -07005231 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5232 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005233#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005234 if (m_enable_android_native_buffers) {
5235 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5236 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5237 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005238#endif
5239
Arun Menon906de572013-06-18 17:01:40 -07005240 post_event(OMX_CommandPortDisable,
5241 OMX_CORE_OUTPUT_PORT_INDEX,
5242 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005243 }
Arun Menon906de572013-06-18 17:01:40 -07005244 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005245 eRet = OMX_ErrorBadPortIndex;
5246 }
Arun Menon906de572013-06-18 17:01:40 -07005247 if ((eRet == OMX_ErrorNone) &&
5248 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5249 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005250 // Send the callback now
5251 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5252 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005253 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005254 }
5255 }
5256 return eRet;
5257}
5258
5259
5260/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005261 FUNCTION
5262 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005263
Arun Menon906de572013-06-18 17:01:40 -07005264 DESCRIPTION
5265 This routine is used to push the encoded video frames to
5266 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005267
Arun Menon906de572013-06-18 17:01:40 -07005268 PARAMETERS
5269 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005270
Arun Menon906de572013-06-18 17:01:40 -07005271 RETURN VALUE
5272 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005273
Arun Menon906de572013-06-18 17:01:40 -07005274 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005275OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005276 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005277{
Arun Menon906de572013-06-18 17:01:40 -07005278 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5279 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005280
Arun Menon906de572013-06-18 17:01:40 -07005281 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5282 codec_config_flag = true;
5283 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5284 } else {
5285 codec_config_flag = false;
5286 }
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07005287
Arun Menon906de572013-06-18 17:01:40 -07005288 if (m_state == OMX_StateInvalid) {
5289 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5290 return OMX_ErrorInvalidState;
5291 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005292
Arun Menon906de572013-06-18 17:01:40 -07005293 if (buffer == NULL) {
5294 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5295 return OMX_ErrorBadParameter;
5296 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005297
Arun Menon906de572013-06-18 17:01:40 -07005298 if (!m_inp_bEnabled) {
5299 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5300 return OMX_ErrorIncorrectStateOperation;
5301 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005302
Arun Menon906de572013-06-18 17:01:40 -07005303 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
5304 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
5305 return OMX_ErrorBadPortIndex;
5306 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005307
5308#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005309 if (iDivXDrmDecrypt) {
5310 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5311 if (drmErr != OMX_ErrorNone) {
5312 // this error can be ignored
5313 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5314 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005315 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005316#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005317 if (perf_flag) {
5318 if (!latency) {
5319 dec_time.stop();
5320 latency = dec_time.processing_time_us();
5321 dec_time.start();
5322 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005323 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005324
Arun Menon906de572013-06-18 17:01:40 -07005325 if (arbitrary_bytes) {
5326 nBufferIndex = buffer - m_inp_heap_ptr;
5327 } else {
5328 if (input_use_buffer == true) {
5329 nBufferIndex = buffer - m_inp_heap_ptr;
5330 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5331 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5332 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5333 buffer = &m_inp_mem_ptr[nBufferIndex];
5334 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5335 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5336 } else {
5337 nBufferIndex = buffer - m_inp_mem_ptr;
5338 }
5339 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005340
Arun Menon906de572013-06-18 17:01:40 -07005341 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
5342 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5343 return OMX_ErrorBadParameter;
5344 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005345
Arun Menon906de572013-06-18 17:01:40 -07005346 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5347 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5348 if (arbitrary_bytes) {
5349 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005350 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005351 } else {
5352 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5353 set_frame_rate(buffer->nTimeStamp);
5354 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5355 }
5356 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005357}
5358
5359/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005360 FUNCTION
5361 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005362
Arun Menon906de572013-06-18 17:01:40 -07005363 DESCRIPTION
5364 This routine is used to push the encoded video frames to
5365 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005366
Arun Menon906de572013-06-18 17:01:40 -07005367 PARAMETERS
5368 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005369
Arun Menon906de572013-06-18 17:01:40 -07005370 RETURN VALUE
5371 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005372
Arun Menon906de572013-06-18 17:01:40 -07005373 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005374OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005375 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005376{
Arun Menon906de572013-06-18 17:01:40 -07005377 int push_cnt = 0,i=0;
5378 unsigned nPortIndex = 0;
5379 OMX_ERRORTYPE ret = OMX_ErrorNone;
5380 struct vdec_input_frameinfo frameinfo;
5381 struct vdec_bufferpayload *temp_buffer;
5382 struct vdec_seqheader seq_header;
5383 bool port_setting_changed = true;
5384 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005385
Arun Menon906de572013-06-18 17:01:40 -07005386 /*Should we generate a Aync error event*/
5387 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
5388 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5389 return OMX_ErrorBadParameter;
5390 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005391
Arun Menon906de572013-06-18 17:01:40 -07005392 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005393
Arun Menon906de572013-06-18 17:01:40 -07005394 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
5395 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5396 nPortIndex);
5397 return OMX_ErrorBadParameter;
5398 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005399
Arun Menon906de572013-06-18 17:01:40 -07005400 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005401
Arun Menon906de572013-06-18 17:01:40 -07005402 /* return zero length and not an EOS buffer */
5403 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5404 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
5405 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5406 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5407 OMX_COMPONENT_GENERATE_EBD);
5408 return OMX_ErrorNone;
5409 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005410
5411
Arun Menon906de572013-06-18 17:01:40 -07005412 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5413 mp4StreamType psBits;
5414 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5415 psBits.numBytes = buffer->nFilledLen;
5416 mp4_headerparser.parseHeader(&psBits);
5417 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5418 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5419 if (not_coded_vop) {
5420 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
5421 buffer->nFilledLen,frame_count);
5422 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
5423 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5424 not_coded_vop = false;
5425 buffer->nFilledLen = 0;
5426 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005427 }
5428 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005429
Arun Menon906de572013-06-18 17:01:40 -07005430 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005431
Arun Menon906de572013-06-18 17:01:40 -07005432 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005433
Arun Menon906de572013-06-18 17:01:40 -07005434 ) {
5435 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5436 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5437 OMX_COMPONENT_GENERATE_EBD);
5438 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005439 }
5440
Arun Menon906de572013-06-18 17:01:40 -07005441 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005442
Arun Menon906de572013-06-18 17:01:40 -07005443 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) {
5444 return OMX_ErrorBadParameter;
5445 }
5446 /* If its first frame, H264 codec and reject is true, then parse the nal
5447 and get the profile. Based on this, reject the clip playback */
5448 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5449 m_reject_avc_1080p_mp) {
5450 first_frame = 1;
5451 DEBUG_PRINT_ERROR("\nParse nal to get the profile");
5452 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5453 NALU_TYPE_SPS);
5454 m_profile = h264_parser->get_profile();
5455 ret = is_video_session_supported();
5456 if (ret) {
5457 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5458 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5459 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5460 m_state = OMX_StateInvalid;
5461 return OMX_ErrorNone;
5462 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005463 }
5464
Arun Menon906de572013-06-18 17:01:40 -07005465 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5466 /*for use buffer we need to memcpy the data*/
5467 temp_buffer->buffer_len = buffer->nFilledLen;
5468
5469 if (input_use_buffer) {
5470 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5471 if (arbitrary_bytes) {
5472 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5473 } else {
5474 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5475 buffer->nFilledLen);
5476 }
5477 } else {
5478 return OMX_ErrorBadParameter;
5479 }
5480
5481 }
5482
5483 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5484 frameinfo.client_data = (void *) buffer;
5485 frameinfo.datalen = temp_buffer->buffer_len;
5486 frameinfo.flags = 0;
5487 frameinfo.offset = buffer->nOffset;
5488 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5489 frameinfo.pmem_offset = temp_buffer->offset;
5490 frameinfo.timestamp = buffer->nTimeStamp;
5491 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5492 DEBUG_PRINT_LOW("ETB: dmx enabled");
5493 if (m_demux_entries == 0) {
5494 extract_demux_addr_offsets(buffer);
5495 }
5496
5497 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5498 handle_demux_data(buffer);
5499 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5500 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5501 } else {
5502 frameinfo.desc_addr = NULL;
5503 frameinfo.desc_size = 0;
5504 }
5505 if (!arbitrary_bytes) {
5506 frameinfo.flags |= buffer->nFlags;
5507 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005508
5509#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005510 if (m_debug_timestamp) {
5511 if (arbitrary_bytes) {
5512 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5513 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5514 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5515 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5516 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5517 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005518 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005519#endif
5520
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005521log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005522
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005523if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005524 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5525 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5526 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005527
Arun Menon906de572013-06-18 17:01:40 -07005528 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5529 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5530 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5531 h264_scratch.nFilledLen = 0;
5532 nal_count = 0;
5533 look_ahead_nal = false;
5534 frame_count = 0;
5535 if (m_frame_parser.mutils)
5536 m_frame_parser.mutils->initialize_frame_checking_environment();
5537 m_frame_parser.flush();
5538 h264_last_au_ts = LLONG_MAX;
5539 h264_last_au_flags = 0;
5540 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5541 m_demux_entries = 0;
5542 }
5543 struct v4l2_buffer buf;
5544 struct v4l2_plane plane;
5545 memset( (void *)&buf, 0, sizeof(buf));
5546 memset( (void *)&plane, 0, sizeof(plane));
5547 int rc;
5548 unsigned long print_count;
5549 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005550 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Arun Menon906de572013-06-18 17:01:40 -07005551 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
5552 }
5553 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5554 buf.index = nPortIndex;
5555 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5556 buf.memory = V4L2_MEMORY_USERPTR;
5557 plane.bytesused = temp_buffer->buffer_len;
5558 plane.length = drv_ctx.ip_buf.buffer_size;
5559 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5560 (unsigned long)temp_buffer->offset;
5561 plane.reserved[0] = temp_buffer->pmem_fd;
5562 plane.reserved[1] = temp_buffer->offset;
5563 plane.data_offset = 0;
5564 buf.m.planes = &plane;
5565 buf.length = 1;
5566 if (frameinfo.timestamp >= LLONG_MAX) {
5567 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5568 }
5569 //assumption is that timestamp is in milliseconds
5570 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5571 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5572 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5573 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005574
Arun Menon906de572013-06-18 17:01:40 -07005575 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5576 if (rc) {
5577 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5578 return OMX_ErrorHardware;
5579 }
5580 if (!streaming[OUTPUT_PORT]) {
5581 enum v4l2_buf_type buf_type;
5582 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005583
Arun Menon906de572013-06-18 17:01:40 -07005584 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005585 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
Arun Menon906de572013-06-18 17:01:40 -07005586 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5587 if (!ret) {
5588 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
5589 streaming[OUTPUT_PORT] = true;
5590 } else {
5591 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
5592 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5593 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5594 OMX_COMPONENT_GENERATE_EBD);
5595 return OMX_ErrorBadParameter;
5596 }
5597 }
5598 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5599 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5600 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005601
Arun Menon906de572013-06-18 17:01:40 -07005602 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005603}
5604
5605/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005606 FUNCTION
5607 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005608
Arun Menon906de572013-06-18 17:01:40 -07005609 DESCRIPTION
5610 IL client uses this method to release the frame buffer
5611 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005612
Arun Menon906de572013-06-18 17:01:40 -07005613 PARAMETERS
5614 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005615
Arun Menon906de572013-06-18 17:01:40 -07005616 RETURN VALUE
5617 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005618
Arun Menon906de572013-06-18 17:01:40 -07005619 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005620OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005621 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005622{
Arun Menonbdb80b02013-08-12 17:45:54 -07005623#ifdef META_DATA_MODE_SUPPORTED
5624 if (dynamic_buf_mode) {
5625 private_handle_t *handle = NULL;
5626 struct VideoDecoderOutputMetaData *meta;
5627 OMX_U8 *buff = NULL;
5628 unsigned int nPortIndex = 0;
5629
5630 if (!buffer || !buffer->pBuffer) {
5631 DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
5632 return OMX_ErrorBadParameter;
5633 }
5634
5635 //get the buffer type and fd info
5636 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5637 handle = (private_handle_t *)meta->pHandle;
5638 DEBUG_PRINT_LOW("FTB: buftype: %d bufhndl: %p", meta->eType, meta->pHandle);
5639
5640 //map the buffer handle based on the size set on output port definition.
5641 if (!secure_mode) {
5642 buff = (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5643 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
5644 } else {
5645 buff = (OMX_U8*) buffer;
5646 }
5647
5648 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5649 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5650 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
5651 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5652 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = buff;
5653 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5654 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5655 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5656 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5657 }
5658#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07005659
Arun Menon906de572013-06-18 17:01:40 -07005660 if (m_state == OMX_StateInvalid) {
5661 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5662 return OMX_ErrorInvalidState;
5663 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005664
Arun Menon906de572013-06-18 17:01:40 -07005665 if (!m_out_bEnabled) {
5666 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5667 return OMX_ErrorIncorrectStateOperation;
5668 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005669
Arun Menon906de572013-06-18 17:01:40 -07005670 if (buffer == NULL ||
5671 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) {
5672 return OMX_ErrorBadParameter;
5673 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005674
Arun Menon906de572013-06-18 17:01:40 -07005675 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
5676 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
5677 return OMX_ErrorBadPortIndex;
5678 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005679
Arun Menon906de572013-06-18 17:01:40 -07005680 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5681 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5682 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005683}
5684/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005685 FUNCTION
5686 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005687
Arun Menon906de572013-06-18 17:01:40 -07005688 DESCRIPTION
5689 IL client uses this method to release the frame buffer
5690 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005691
Arun Menon906de572013-06-18 17:01:40 -07005692 PARAMETERS
5693 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005694
Arun Menon906de572013-06-18 17:01:40 -07005695 RETURN VALUE
5696 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005697
Arun Menon906de572013-06-18 17:01:40 -07005698 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005699OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005700 OMX_IN OMX_HANDLETYPE hComp,
5701 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005702{
Arun Menon906de572013-06-18 17:01:40 -07005703 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5704 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5705 unsigned nPortIndex = 0;
5706 struct vdec_fillbuffer_cmd fillbuffer;
5707 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5708 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005709
Arun Menon906de572013-06-18 17:01:40 -07005710 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005711
Arun Menon906de572013-06-18 17:01:40 -07005712 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5713 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005714
Arun Menon906de572013-06-18 17:01:40 -07005715 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5716 bufferAdd, bufferAdd->pBuffer);
5717 /*Return back the output buffer to client*/
5718 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
5719 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5720 buffer->nFilledLen = 0;
5721 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5722 return OMX_ErrorNone;
5723 }
5724 pending_output_buffers++;
5725 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5726 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5727 if (ptr_respbuffer) {
5728 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5729 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005730
Arun Menon906de572013-06-18 17:01:40 -07005731 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5732 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5733 buffer->nFilledLen = 0;
5734 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5735 pending_output_buffers--;
5736 return OMX_ErrorBadParameter;
5737 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005738
Arun Menon906de572013-06-18 17:01:40 -07005739 int rc = 0;
5740 struct v4l2_buffer buf;
5741 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5742 memset( (void *)&buf, 0, sizeof(buf));
5743 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5744 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005745
Arun Menon906de572013-06-18 17:01:40 -07005746 buf.index = nPortIndex;
5747 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5748 buf.memory = V4L2_MEMORY_USERPTR;
5749 plane[0].bytesused = buffer->nFilledLen;
5750 plane[0].length = drv_ctx.op_buf.buffer_size;
5751 plane[0].m.userptr =
5752 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5753 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5754 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5755 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5756 plane[0].data_offset = 0;
5757 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5758 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5759 plane[extra_idx].bytesused = 0;
5760 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5761 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 -07005762#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005763 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005764#endif
Arun Menon906de572013-06-18 17:01:40 -07005765 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5766 plane[extra_idx].data_offset = 0;
5767 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5768 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5769 return OMX_ErrorBadParameter;
5770 }
5771 buf.m.planes = plane;
5772 buf.length = drv_ctx.num_planes;
Arun Menonbdb80b02013-08-12 17:45:54 -07005773 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d\n",
5774 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5775
Arun Menon906de572013-06-18 17:01:40 -07005776 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5777 if (rc) {
5778 /*TODO: How to handle this case */
5779 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5780 }
Arun Menon906de572013-06-18 17:01:40 -07005781return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005782}
5783
5784/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005785 FUNCTION
5786 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005787
Arun Menon906de572013-06-18 17:01:40 -07005788 DESCRIPTION
5789 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005790
Arun Menon906de572013-06-18 17:01:40 -07005791 PARAMETERS
5792 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005793
Arun Menon906de572013-06-18 17:01:40 -07005794 RETURN VALUE
5795 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005796
Arun Menon906de572013-06-18 17:01:40 -07005797 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005798OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005799 OMX_IN OMX_CALLBACKTYPE* callbacks,
5800 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005801{
5802
Arun Menon906de572013-06-18 17:01:40 -07005803 m_cb = *callbacks;
5804 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5805 m_cb.EventHandler,m_cb.FillBufferDone);
5806 m_app_data = appData;
5807 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005808}
5809
5810/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005811 FUNCTION
5812 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005813
Arun Menon906de572013-06-18 17:01:40 -07005814 DESCRIPTION
5815 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005816
Arun Menon906de572013-06-18 17:01:40 -07005817 PARAMETERS
5818 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005819
Arun Menon906de572013-06-18 17:01:40 -07005820 RETURN VALUE
5821 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005822
Arun Menon906de572013-06-18 17:01:40 -07005823 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005824OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5825{
5826#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005827 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005828 delete iDivXDrmDecrypt;
5829 iDivXDrmDecrypt=NULL;
5830 }
5831#endif //_ANDROID_
5832
Shalaj Jain286b0062013-02-21 20:35:48 -08005833 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005834 if (OMX_StateLoaded != m_state) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005835 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
Arun Menon906de572013-06-18 17:01:40 -07005836 m_state);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005837 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005838 } else {
5839 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005840 }
5841
5842 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005843 if (m_out_mem_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005844 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005845 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5846 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005847 }
5848#ifdef _ANDROID_ICS_
5849 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5850#endif
5851 }
5852
5853 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005854 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005855 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005856 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5857 if (m_inp_mem_ptr)
5858 free_input_buffer (i,&m_inp_mem_ptr[i]);
5859 else
5860 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005861 }
5862 }
5863 free_input_buffer_header();
5864 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005865 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005866 free(h264_scratch.pBuffer);
5867 h264_scratch.pBuffer = NULL;
5868 }
5869
Arun Menon906de572013-06-18 17:01:40 -07005870 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005871 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005872 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005873 }
5874
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07005875 if (m_frame_parser.mutils) {
5876 DEBUG_PRINT_LOW("\n Free utils parser");
5877 delete (m_frame_parser.mutils);
5878 m_frame_parser.mutils = NULL;
5879 }
5880
Arun Menon906de572013-06-18 17:01:40 -07005881 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005882 free(m_platform_list);
5883 m_platform_list = NULL;
5884 }
Arun Menon906de572013-06-18 17:01:40 -07005885 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005886 free(m_vendor_config.pData);
5887 m_vendor_config.pData = NULL;
5888 }
5889
5890 // Reset counters in mesg queues
5891 m_ftb_q.m_size=0;
5892 m_cmd_q.m_size=0;
5893 m_etb_q.m_size=0;
5894 m_ftb_q.m_read = m_ftb_q.m_write =0;
5895 m_cmd_q.m_read = m_cmd_q.m_write =0;
5896 m_etb_q.m_read = m_etb_q.m_write =0;
5897#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005898 if (m_debug_timestamp) {
5899 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005900 }
5901#endif
5902
5903 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
5904 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07005905 // NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005906 DEBUG_PRINT_HIGH("\n Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07005907
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005908 if (m_debug.infile) {
5909 fclose(m_debug.infile);
5910 m_debug.infile = NULL;
5911 }
5912 if (m_debug.outfile) {
5913 fclose(m_debug.outfile);
5914 m_debug.outfile = NULL;
5915 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005916#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07005917 if (outputExtradataFile)
5918 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005919#endif
Arun Menon906de572013-06-18 17:01:40 -07005920 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
5921 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005922}
5923
5924/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005925 FUNCTION
5926 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07005927
Arun Menon906de572013-06-18 17:01:40 -07005928 DESCRIPTION
5929 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005930
Arun Menon906de572013-06-18 17:01:40 -07005931 PARAMETERS
5932 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005933
Arun Menon906de572013-06-18 17:01:40 -07005934 RETURN VALUE
5935 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005936
Arun Menon906de572013-06-18 17:01:40 -07005937 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005938OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005939 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5940 OMX_IN OMX_U32 port,
5941 OMX_IN OMX_PTR appData,
5942 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005943{
Arun Menon906de572013-06-18 17:01:40 -07005944 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
5945 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
5946 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005947
5948#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005949 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
5950 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005951#else
Arun Menon906de572013-06-18 17:01:40 -07005952 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005953#endif
Arun Menon906de572013-06-18 17:01:40 -07005954 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
5955 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
5956 DEBUG_PRINT_ERROR("\n ");
5957 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005958#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005959 if (m_display_id == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005960 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
5961 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005962 }
5963 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
5964 eglGetProcAddress("eglQueryImageKHR");
5965 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
5966 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
5967 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005968#else //with OMX test app
5969 struct temp_egl {
5970 int pmem_fd;
5971 int offset;
5972 };
5973 struct temp_egl *temp_egl_id = NULL;
5974 void * pmemPtr = (void *) eglImage;
5975 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07005976 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005977 fd = temp_egl_id->pmem_fd;
5978 offset = temp_egl_id->offset;
5979 }
5980#endif
5981 if (fd < 0) {
5982 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
5983 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005984 }
5985 pmem_info.pmem_fd = (OMX_U32) fd;
5986 pmem_info.offset = (OMX_U32) offset;
5987 pmem_entry.entry = (void *) &pmem_info;
5988 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5989 pmem_list.entryList = &pmem_entry;
5990 pmem_list.nEntries = 1;
5991 ouput_egl_buffers = true;
5992 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
5993 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
5994 (OMX_U8 *)pmemPtr)) {
5995 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
5996 return OMX_ErrorInsufficientResources;
5997 }
5998 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005999}
6000
6001/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006002 FUNCTION
6003 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006004
Arun Menon906de572013-06-18 17:01:40 -07006005 DESCRIPTION
6006 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006007
Arun Menon906de572013-06-18 17:01:40 -07006008 PARAMETERS
6009 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006010
Arun Menon906de572013-06-18 17:01:40 -07006011 RETURN VALUE
6012 OMX Error None if everything is successful.
6013 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006014OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006015 OMX_OUT OMX_U8* role,
6016 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006017{
Arun Menon906de572013-06-18 17:01:40 -07006018 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006019
Arun Menon906de572013-06-18 17:01:40 -07006020 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6021 if ((0 == index) && role) {
6022 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6023 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6024 } else {
6025 eRet = OMX_ErrorNoMore;
6026 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006027 }
Arun Menon906de572013-06-18 17:01:40 -07006028 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6029 if ((0 == index) && role) {
6030 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6031 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6032 } else {
6033 eRet = OMX_ErrorNoMore;
6034 }
6035 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6036 if ((0 == index) && role) {
6037 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6038 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6039 } else {
6040 DEBUG_PRINT_LOW("\n No more roles \n");
6041 eRet = OMX_ErrorNoMore;
6042 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006043 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006044
Arun Menon906de572013-06-18 17:01:40 -07006045 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6046 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6047 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006048
Shalaj Jain273b3e02012-06-22 19:08:03 -07006049 {
Arun Menon906de572013-06-18 17:01:40 -07006050 if ((0 == index) && role) {
6051 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6052 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6053 } else {
6054 DEBUG_PRINT_LOW("\n No more roles \n");
6055 eRet = OMX_ErrorNoMore;
6056 }
6057 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6058 if ((0 == index) && role) {
6059 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6060 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6061 } else {
6062 DEBUG_PRINT_LOW("\n No more roles \n");
6063 eRet = OMX_ErrorNoMore;
6064 }
6065 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6066 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6067 ) {
6068 if ((0 == index) && role) {
6069 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6070 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6071 } else {
6072 DEBUG_PRINT_LOW("\n No more roles \n");
6073 eRet = OMX_ErrorNoMore;
6074 }
6075 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6076 if ((0 == index) && role) {
6077 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6078 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6079 } else {
6080 DEBUG_PRINT_LOW("\n No more roles \n");
6081 eRet = OMX_ErrorNoMore;
6082 }
6083 } else {
6084 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6085 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006086 }
Arun Menon906de572013-06-18 17:01:40 -07006087 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006088}
6089
6090
6091
6092
6093/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006094 FUNCTION
6095 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006096
Arun Menon906de572013-06-18 17:01:40 -07006097 DESCRIPTION
6098 Checks if entire buffer pool is allocated by IL Client or not.
6099 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006100
Arun Menon906de572013-06-18 17:01:40 -07006101 PARAMETERS
6102 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006103
Arun Menon906de572013-06-18 17:01:40 -07006104 RETURN VALUE
6105 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006106
Arun Menon906de572013-06-18 17:01:40 -07006107 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006108bool omx_vdec::allocate_done(void)
6109{
Arun Menon906de572013-06-18 17:01:40 -07006110 bool bRet = false;
6111 bool bRet_In = false;
6112 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006113
Arun Menon906de572013-06-18 17:01:40 -07006114 bRet_In = allocate_input_done();
6115 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006116
Arun Menon906de572013-06-18 17:01:40 -07006117 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006118 bRet = true;
6119 }
Arun Menon906de572013-06-18 17:01:40 -07006120
6121 return bRet;
6122}
6123/* ======================================================================
6124 FUNCTION
6125 omx_vdec::AllocateInputDone
6126
6127 DESCRIPTION
6128 Checks if I/P buffer pool is allocated by IL Client or not.
6129
6130 PARAMETERS
6131 None.
6132
6133 RETURN VALUE
6134 true/false.
6135
6136 ========================================================================== */
6137bool omx_vdec::allocate_input_done(void)
6138{
6139 bool bRet = false;
6140 unsigned i=0;
6141
6142 if (m_inp_mem_ptr == NULL) {
6143 return bRet;
6144 }
6145 if (m_inp_mem_ptr ) {
6146 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6147 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6148 break;
6149 }
6150 }
6151 }
6152 if (i == drv_ctx.ip_buf.actualcount) {
6153 bRet = true;
6154 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6155 }
6156 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6157 m_inp_bPopulated = OMX_TRUE;
6158 }
6159 return bRet;
6160}
6161/* ======================================================================
6162 FUNCTION
6163 omx_vdec::AllocateOutputDone
6164
6165 DESCRIPTION
6166 Checks if entire O/P buffer pool is allocated by IL Client or not.
6167
6168 PARAMETERS
6169 None.
6170
6171 RETURN VALUE
6172 true/false.
6173
6174 ========================================================================== */
6175bool omx_vdec::allocate_output_done(void)
6176{
6177 bool bRet = false;
6178 unsigned j=0;
6179
6180 if (m_out_mem_ptr == NULL) {
6181 return bRet;
6182 }
6183
6184 if (m_out_mem_ptr) {
6185 for (; j < drv_ctx.op_buf.actualcount; j++) {
6186 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6187 break;
6188 }
6189 }
6190 }
6191
6192 if (j == drv_ctx.op_buf.actualcount) {
6193 bRet = true;
6194 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6195 if (m_out_bEnabled)
6196 m_out_bPopulated = OMX_TRUE;
6197 }
6198
6199 return bRet;
6200}
6201
6202/* ======================================================================
6203 FUNCTION
6204 omx_vdec::ReleaseDone
6205
6206 DESCRIPTION
6207 Checks if IL client has released all the buffers.
6208
6209 PARAMETERS
6210 None.
6211
6212 RETURN VALUE
6213 true/false
6214
6215 ========================================================================== */
6216bool omx_vdec::release_done(void)
6217{
6218 bool bRet = false;
6219
6220 if (release_input_done()) {
6221 if (release_output_done()) {
6222 bRet = true;
6223 }
6224 }
6225 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006226}
6227
6228
6229/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006230 FUNCTION
6231 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006232
Arun Menon906de572013-06-18 17:01:40 -07006233 DESCRIPTION
6234 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006235
Arun Menon906de572013-06-18 17:01:40 -07006236 PARAMETERS
6237 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006238
Arun Menon906de572013-06-18 17:01:40 -07006239 RETURN VALUE
6240 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006241
Arun Menon906de572013-06-18 17:01:40 -07006242 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006243bool omx_vdec::release_output_done(void)
6244{
Arun Menon906de572013-06-18 17:01:40 -07006245 bool bRet = false;
6246 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006247
Arun Menon906de572013-06-18 17:01:40 -07006248 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6249 if (m_out_mem_ptr) {
6250 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6251 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6252 break;
6253 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006254 }
Arun Menon906de572013-06-18 17:01:40 -07006255 if (j == drv_ctx.op_buf.actualcount) {
6256 m_out_bm_count = 0;
6257 bRet = true;
6258 }
6259 } else {
6260 m_out_bm_count = 0;
6261 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006262 }
Arun Menon906de572013-06-18 17:01:40 -07006263 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006264}
6265/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006266 FUNCTION
6267 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006268
Arun Menon906de572013-06-18 17:01:40 -07006269 DESCRIPTION
6270 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006271
Arun Menon906de572013-06-18 17:01:40 -07006272 PARAMETERS
6273 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006274
Arun Menon906de572013-06-18 17:01:40 -07006275 RETURN VALUE
6276 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006277
Arun Menon906de572013-06-18 17:01:40 -07006278 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006279bool omx_vdec::release_input_done(void)
6280{
Arun Menon906de572013-06-18 17:01:40 -07006281 bool bRet = false;
6282 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006283
Arun Menon906de572013-06-18 17:01:40 -07006284 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6285 if (m_inp_mem_ptr) {
6286 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6287 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6288 break;
6289 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006290 }
Arun Menon906de572013-06-18 17:01:40 -07006291 if (j==drv_ctx.ip_buf.actualcount) {
6292 bRet = true;
6293 }
6294 } else {
6295 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006296 }
Arun Menon906de572013-06-18 17:01:40 -07006297 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006298}
6299
6300OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006301 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006302{
Arun Menon906de572013-06-18 17:01:40 -07006303 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6304 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) {
6305 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6306 return OMX_ErrorBadParameter;
6307 } else if (output_flush_progress) {
6308 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6309 buffer->nFilledLen = 0;
6310 buffer->nTimeStamp = 0;
6311 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6312 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6313 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006314 }
6315
Arun Menon906de572013-06-18 17:01:40 -07006316 if (m_debug_extradata) {
6317 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
6318 DEBUG_PRINT_HIGH("\n");
6319 DEBUG_PRINT_HIGH("***************************************************\n");
6320 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
6321 DEBUG_PRINT_HIGH("***************************************************\n");
6322 }
6323
6324 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
6325 DEBUG_PRINT_HIGH("\n");
6326 DEBUG_PRINT_HIGH("***************************************************\n");
6327 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
6328 DEBUG_PRINT_HIGH("***************************************************\n");
6329 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006330 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006331
6332
Arun Menon906de572013-06-18 17:01:40 -07006333 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6334 buffer, buffer->pBuffer);
6335 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006336
Arun Menonbdb80b02013-08-12 17:45:54 -07006337#ifdef META_DATA_MODE_SUPPORTED
6338 if (dynamic_buf_mode && !secure_mode) {
6339 unsigned int nPortIndex = 0;
6340 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6341 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6342 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6343 }
6344#endif
6345
Arun Menon906de572013-06-18 17:01:40 -07006346 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6347 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6348 if (!output_flush_progress)
6349 post_event((unsigned)NULL, (unsigned)NULL,
6350 OMX_COMPONENT_GENERATE_EOS_DONE);
6351
6352 if (psource_frame) {
6353 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6354 psource_frame = NULL;
6355 }
6356 if (pdest_frame) {
6357 pdest_frame->nFilledLen = 0;
6358 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6359 (unsigned)NULL);
6360 pdest_frame = NULL;
6361 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006362 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006363
Arun Menon906de572013-06-18 17:01:40 -07006364 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006365 log_output_buffers(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006366
Praneeth Paladugudd29c282013-09-12 15:41:47 -07006367 if (!output_flush_progress && (buffer->nFilledLen > 0)) {
6368 DEBUG_PRINT_LOW("Processing extradata");
6369 handle_extradata(buffer);
6370 }
6371
Arun Menon906de572013-06-18 17:01:40 -07006372 /* For use buffer we need to copy the data */
6373 if (!output_flush_progress) {
6374 /* This is the error check for non-recoverable errros */
6375 bool is_duplicate_ts_valid = true;
6376 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006377
Arun Menon906de572013-06-18 17:01:40 -07006378 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6379 output_capability == V4L2_PIX_FMT_MPEG2 ||
6380 output_capability == V4L2_PIX_FMT_DIVX ||
6381 output_capability == V4L2_PIX_FMT_DIVX_311)
6382 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006383
Arun Menon906de572013-06-18 17:01:40 -07006384 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6385 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6386 if (mbaff) {
6387 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306388 }
Arun Menon906de572013-06-18 17:01:40 -07006389 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306390
Arun Menon906de572013-06-18 17:01:40 -07006391 if (buffer->nFilledLen > 0) {
6392 time_stamp_dts.get_next_timestamp(buffer,
6393 is_interlaced && is_duplicate_ts_valid);
6394 if (m_debug_timestamp) {
6395 {
6396 OMX_TICKS expected_ts = 0;
6397 m_timestamp_list.pop_min_ts(expected_ts);
6398 if (is_interlaced && is_duplicate_ts_valid) {
6399 m_timestamp_list.pop_min_ts(expected_ts);
6400 }
6401 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6402 buffer->nTimeStamp, expected_ts);
6403
6404 if (buffer->nTimeStamp != expected_ts) {
6405 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6406 }
6407 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306408 }
Arun Menon906de572013-06-18 17:01:40 -07006409 } else {
6410 m_inp_err_count++;
6411 time_stamp_dts.remove_time_stamp(
6412 buffer->nTimeStamp,
6413 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306414 }
Arun Menon906de572013-06-18 17:01:40 -07006415
6416
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006417 }
Arun Menon906de572013-06-18 17:01:40 -07006418 if (m_cb.FillBufferDone) {
6419 if (buffer->nFilledLen > 0) {
Arun Menon906de572013-06-18 17:01:40 -07006420 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6421 set_frame_rate(buffer->nTimeStamp);
6422 else if (arbitrary_bytes)
6423 adjust_timestamp(buffer->nTimeStamp);
6424 if (perf_flag) {
6425 if (!proc_frms) {
6426 dec_time.stop();
6427 latency = dec_time.processing_time_us() - latency;
6428 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6429 dec_time.start();
6430 fps_metrics.start();
6431 }
6432 proc_frms++;
6433 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6434 OMX_U64 proc_time = 0;
6435 fps_metrics.stop();
6436 proc_time = fps_metrics.processing_time_us();
6437 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006438 proc_frms, (float)proc_time / 1e6,
6439 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006440 proc_frms = 0;
6441 }
6442 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006443
6444#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006445 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006446
Arun Menon906de572013-06-18 17:01:40 -07006447 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6448 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6449 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6450 buffer->nFilledLen + 3)&(~3));
6451 while (p_extra &&
6452 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
6453 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6454 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6455 if (p_extra->eType == OMX_ExtraDataNone) {
6456 break;
6457 }
6458 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6459 }
6460 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006461#endif
Arun Menon906de572013-06-18 17:01:40 -07006462 }
6463 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6464 prev_ts = LLONG_MAX;
6465 rst_prev_ts = true;
6466 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006467
Arun Menon906de572013-06-18 17:01:40 -07006468 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6469 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6470 buffer->pPlatformPrivate)->entryList->entry;
6471 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006472 OMX_BUFFERHEADERTYPE *il_buffer;
6473 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6474 if (il_buffer)
6475 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6476 else {
6477 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6478 return OMX_ErrorBadParameter;
6479 }
6480 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
6481 } else {
6482 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006483 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006484
Arun Menon906de572013-06-18 17:01:40 -07006485 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006486}
6487
6488OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006489 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006490{
6491
Arun Menon906de572013-06-18 17:01:40 -07006492 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006493 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006494 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006495 }
6496
6497 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006498 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006499 pending_input_buffers--;
6500
Arun Menon906de572013-06-18 17:01:40 -07006501 if (arbitrary_bytes) {
6502 if (pdest_frame == NULL && input_flush_progress == false) {
6503 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6504 pdest_frame = buffer;
6505 buffer->nFilledLen = 0;
6506 buffer->nTimeStamp = LLONG_MAX;
6507 push_input_buffer (hComp);
6508 } else {
6509 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6510 buffer->nFilledLen = 0;
6511 if (!m_input_free_q.insert_entry((unsigned)buffer,
6512 (unsigned)NULL, (unsigned)NULL)) {
6513 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6514 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006515 }
Arun Menon906de572013-06-18 17:01:40 -07006516 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006517 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006518 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006519 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6520 }
6521 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6522 }
6523 return OMX_ErrorNone;
6524}
6525
Shalaj Jain273b3e02012-06-22 19:08:03 -07006526int omx_vdec::async_message_process (void *context, void* message)
6527{
Arun Menon906de572013-06-18 17:01:40 -07006528 omx_vdec* omx = NULL;
6529 struct vdec_msginfo *vdec_msg = NULL;
6530 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6531 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6532 struct vdec_output_frameinfo *output_respbuf = NULL;
6533 int rc=1;
6534 if (context == NULL || message == NULL) {
6535 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6536 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006537 }
Arun Menon906de572013-06-18 17:01:40 -07006538 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006539
Arun Menon906de572013-06-18 17:01:40 -07006540 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006541
Arun Menon906de572013-06-18 17:01:40 -07006542 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006543
Arun Menon906de572013-06-18 17:01:40 -07006544 case VDEC_MSG_EVT_HW_ERROR:
6545 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6546 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6547 break;
6548
6549 case VDEC_MSG_RESP_START_DONE:
6550 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6551 OMX_COMPONENT_GENERATE_START_DONE);
6552 break;
6553
6554 case VDEC_MSG_RESP_STOP_DONE:
6555 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6556 OMX_COMPONENT_GENERATE_STOP_DONE);
6557 break;
6558
6559 case VDEC_MSG_RESP_RESUME_DONE:
6560 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6561 OMX_COMPONENT_GENERATE_RESUME_DONE);
6562 break;
6563
6564 case VDEC_MSG_RESP_PAUSE_DONE:
6565 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6566 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6567 break;
6568
6569 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6570 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6571 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6572 break;
6573 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6574 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6575 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6576 break;
6577 case VDEC_MSG_RESP_INPUT_FLUSHED:
6578 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6579
6580 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6581 vdec_msg->msgdata.input_frame_clientdata; */
6582
6583 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6584 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6585 if (omxhdr == NULL ||
6586 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) {
6587 omxhdr = NULL;
6588 vdec_msg->status_code = VDEC_S_EFATAL;
6589 }
6590 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6591 DEBUG_PRINT_HIGH("Unsupported input");
6592 omx->omx_report_error ();
6593 }
6594 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6595 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6596 }
6597 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6598 OMX_COMPONENT_GENERATE_EBD);
6599 break;
6600 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6601 int64_t *timestamp;
6602 timestamp = (int64_t *) malloc(sizeof(int64_t));
6603 if (timestamp) {
6604 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6605 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6606 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6607 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6608 vdec_msg->msgdata.output_frame.time_stamp);
6609 }
6610 break;
6611 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6612 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6613
6614 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6615 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6616 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6617 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6618 vdec_msg->msgdata.output_frame.pic_type);
6619
6620 if (omxhdr && omxhdr->pOutputPortPrivate &&
6621 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6622 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6623 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006624#ifdef META_DATA_MODE_SUPPORTED
6625 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6626 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6627 }
6628#endif
Arun Menon906de572013-06-18 17:01:40 -07006629 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6630 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6631 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6632 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6633 omxhdr->nFlags = 0;
6634
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006635 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006636 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6637 //rc = -1;
6638 }
6639 if (omxhdr->nFilledLen) {
6640 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6641 }
6642 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6643 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6644 } else {
6645 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6646 }
6647 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6648 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6649 }
6650 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6651 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6652 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006653#ifdef META_DATA_MODE_SUPPORTED
6654 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006655 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006656 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6657 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6658 }
6659
6660 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6661 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6662 omxhdr->nOffset);
6663 }
6664#endif
Arun Menon906de572013-06-18 17:01:40 -07006665 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6666 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006667 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006668 omx->time_stamp_dts.remove_time_stamp(
6669 omxhdr->nTimeStamp,
6670 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6671 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006672 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6673 OMX_COMPONENT_GENERATE_FTB);
6674 break;
6675 }
6676 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6677 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6678 }
6679 vdec_msg->msgdata.output_frame.bufferaddr =
6680 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6681 int format_notably_changed = 0;
6682 if (omxhdr->nFilledLen &&
6683 (omxhdr->nFilledLen != omx->prev_n_filled_len)) {
6684 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6685 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6686 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
6687 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6688 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6689 format_notably_changed = 1;
6690 }
6691 }
6692 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6693 vdec_msg->msgdata.output_frame.framesize.left)
6694 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6695 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6696 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6697 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6698 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6699 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6700 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6701 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
6702 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6703 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6704 }
6705 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
6706 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6707 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006708 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6709 omx->drv_ctx.video_resolution.frame_width) {
6710 vdec_msg->msgdata.output_frame.framesize.left = 0;
6711 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6712 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6713 }
6714 }
6715 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6716 omx->drv_ctx.video_resolution.frame_height) {
6717 vdec_msg->msgdata.output_frame.framesize.top = 0;
6718 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6719 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6720 }
6721 }
6722 DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d\n",
6723 vdec_msg->msgdata.output_frame.framesize.left,
6724 vdec_msg->msgdata.output_frame.framesize.top,
6725 vdec_msg->msgdata.output_frame.framesize.right,
6726 vdec_msg->msgdata.output_frame.framesize.bottom,
6727 omx->drv_ctx.video_resolution.frame_width,
6728 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006729 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6730 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6731 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6732 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6733 format_notably_changed = 1;
6734 }
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006735 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d\n",
6736 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6737 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006738 if (format_notably_changed) {
6739 if (omx->is_video_session_supported()) {
6740 omx->post_event (NULL, vdec_msg->status_code,
6741 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6742 } else {
6743 if (!omx->client_buffers.update_buffer_req()) {
6744 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6745 }
6746 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6747 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6748 }
6749 }
6750 if (omxhdr->nFilledLen)
6751 omx->prev_n_filled_len = omxhdr->nFilledLen;
6752
6753 output_respbuf = (struct vdec_output_frameinfo *)\
6754 omxhdr->pOutputPortPrivate;
6755 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6756 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6757 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6758 output_respbuf->pic_type = PICTURE_TYPE_I;
6759 }
6760 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6761 output_respbuf->pic_type = PICTURE_TYPE_P;
6762 }
6763 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6764 output_respbuf->pic_type = PICTURE_TYPE_B;
6765 }
6766
6767 if (omx->output_use_buffer)
6768 memcpy ( omxhdr->pBuffer, (void *)
6769 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6770 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6771 vdec_msg->msgdata.output_frame.len);
6772 } else
6773 omxhdr->nFilledLen = 0;
6774 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6775 OMX_COMPONENT_GENERATE_FBD);
6776 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6777 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6778 OMX_COMPONENT_GENERATE_EOS_DONE);
6779 else
6780 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6781 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6782 break;
6783 case VDEC_MSG_EVT_CONFIG_CHANGED:
6784 DEBUG_PRINT_HIGH("\n Port settings changed");
6785 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6786 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6787 break;
6788 default:
6789 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006790 }
Arun Menon906de572013-06-18 17:01:40 -07006791 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006792}
6793
6794OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006795 OMX_HANDLETYPE hComp,
6796 OMX_BUFFERHEADERTYPE *buffer
6797 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006798{
Arun Menon906de572013-06-18 17:01:40 -07006799 unsigned address,p2,id;
6800 DEBUG_PRINT_LOW("\n Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006801
Arun Menon906de572013-06-18 17:01:40 -07006802 if (buffer == NULL) {
6803 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006804 }
Arun Menon906de572013-06-18 17:01:40 -07006805 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6806 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
6807 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6808
6809 /* return zero length and not an EOS buffer */
6810 /* return buffer if input flush in progress */
6811 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6812 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
6813 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
6814 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6815 return OMX_ErrorNone;
6816 }
6817
6818 if (psource_frame == NULL) {
6819 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
6820 psource_frame = buffer;
6821 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
6822 push_input_buffer (hComp);
6823 } else {
6824 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
6825 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6826 (unsigned)NULL)) {
6827 return OMX_ErrorBadParameter;
6828 }
6829 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006830
6831
Arun Menon906de572013-06-18 17:01:40 -07006832 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006833}
6834
6835OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6836{
Arun Menon906de572013-06-18 17:01:40 -07006837 unsigned address,p2,id;
6838 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006839
Arun Menon906de572013-06-18 17:01:40 -07006840 if (pdest_frame == NULL || psource_frame == NULL) {
6841 /*Check if we have a destination buffer*/
6842 if (pdest_frame == NULL) {
6843 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
6844 if (m_input_free_q.m_size) {
6845 m_input_free_q.pop_entry(&address,&p2,&id);
6846 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6847 pdest_frame->nFilledLen = 0;
6848 pdest_frame->nTimeStamp = LLONG_MAX;
6849 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
6850 }
6851 }
6852
6853 /*Check if we have a destination buffer*/
6854 if (psource_frame == NULL) {
6855 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
6856 if (m_input_pending_q.m_size) {
6857 m_input_pending_q.pop_entry(&address,&p2,&id);
6858 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
6859 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6860 psource_frame->nTimeStamp);
6861 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6862 psource_frame->nFlags,psource_frame->nFilledLen);
6863
6864 }
6865 }
6866
Shalaj Jain273b3e02012-06-22 19:08:03 -07006867 }
6868
Arun Menon906de572013-06-18 17:01:40 -07006869 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6870 switch (codec_type_parse) {
6871 case CODEC_TYPE_MPEG4:
6872 case CODEC_TYPE_H263:
6873 case CODEC_TYPE_MPEG2:
6874 ret = push_input_sc_codec(hComp);
6875 break;
6876 case CODEC_TYPE_H264:
6877 ret = push_input_h264(hComp);
6878 break;
6879 case CODEC_TYPE_VC1:
6880 ret = push_input_vc1(hComp);
6881 break;
6882 default:
6883 break;
6884 }
6885 if (ret != OMX_ErrorNone) {
6886 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
6887 omx_report_error ();
6888 break;
6889 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006890 }
6891
Arun Menon906de572013-06-18 17:01:40 -07006892 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006893}
6894
6895OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
6896{
Arun Menon906de572013-06-18 17:01:40 -07006897 OMX_U32 partial_frame = 1;
6898 OMX_BOOL generate_ebd = OMX_TRUE;
6899 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006900
Arun Menon906de572013-06-18 17:01:40 -07006901 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
6902 psource_frame,psource_frame->nTimeStamp);
6903 if (m_frame_parser.parse_sc_frame(psource_frame,
6904 pdest_frame,&partial_frame) == -1) {
6905 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
6906 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006907 }
Arun Menon906de572013-06-18 17:01:40 -07006908
6909 if (partial_frame == 0) {
6910 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
6911 pdest_frame->nFilledLen,psource_frame,frame_count);
6912
6913
6914 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
6915 /*First Parsed buffer will have only header Hence skip*/
6916 if (frame_count == 0) {
6917 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
6918
6919 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
6920 codec_type_parse == CODEC_TYPE_DIVX) {
6921 mp4StreamType psBits;
6922 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
6923 psBits.numBytes = pdest_frame->nFilledLen;
6924 mp4_headerparser.parseHeader(&psBits);
6925 }
6926
6927 frame_count++;
6928 } else {
6929 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6930 if (pdest_frame->nFilledLen) {
6931 /*Push the frame to the Decoder*/
6932 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6933 return OMX_ErrorBadParameter;
6934 }
6935 frame_count++;
6936 pdest_frame = NULL;
6937
6938 if (m_input_free_q.m_size) {
6939 m_input_free_q.pop_entry(&address,&p2,&id);
6940 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6941 pdest_frame->nFilledLen = 0;
6942 }
6943 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
6944 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
6945 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
6946 (unsigned)NULL);
6947 pdest_frame = NULL;
6948 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006949 }
Arun Menon906de572013-06-18 17:01:40 -07006950 } else {
6951 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
6952 /*Check if Destination Buffer is full*/
6953 if (pdest_frame->nAllocLen ==
6954 pdest_frame->nFilledLen + pdest_frame->nOffset) {
6955 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
6956 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006957 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006958 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006959
Arun Menon906de572013-06-18 17:01:40 -07006960 if (psource_frame->nFilledLen == 0) {
6961 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6962 if (pdest_frame) {
6963 pdest_frame->nFlags |= psource_frame->nFlags;
6964 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
6965 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6966 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6967 pdest_frame->nFilledLen,frame_count++);
6968 /*Push the frame to the Decoder*/
6969 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6970 return OMX_ErrorBadParameter;
6971 }
6972 frame_count++;
6973 pdest_frame = NULL;
6974 } else {
6975 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
6976 generate_ebd = OMX_FALSE;
6977 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006978 }
Arun Menon906de572013-06-18 17:01:40 -07006979 if (generate_ebd) {
6980 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
6981 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6982 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006983
Arun Menon906de572013-06-18 17:01:40 -07006984 if (m_input_pending_q.m_size) {
6985 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6986 m_input_pending_q.pop_entry(&address,&p2,&id);
6987 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6988 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6989 psource_frame->nTimeStamp);
6990 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6991 psource_frame->nFlags,psource_frame->nFilledLen);
6992 }
6993 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006994 }
Arun Menon906de572013-06-18 17:01:40 -07006995 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006996}
6997
6998OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
6999{
Arun Menon906de572013-06-18 17:01:40 -07007000 OMX_U32 partial_frame = 1;
7001 unsigned address = 0, p2 = 0, id = 0;
7002 OMX_BOOL isNewFrame = OMX_FALSE;
7003 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007004
Arun Menon906de572013-06-18 17:01:40 -07007005 if (h264_scratch.pBuffer == NULL) {
7006 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7007 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007008 }
Arun Menon906de572013-06-18 17:01:40 -07007009 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
7010 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
7011 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
7012 if (h264_scratch.nFilledLen && look_ahead_nal) {
7013 look_ahead_nal = false;
7014 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7015 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007016 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7017 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7018 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Arun Menon906de572013-06-18 17:01:40 -07007019 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007020 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007021 } else {
7022 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007023 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007024 }
Arun Menon906de572013-06-18 17:01:40 -07007025 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007026
7027 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7028 in EOS flag getting associated with the destination
7029 */
7030 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7031 pdest_frame->nFilledLen) {
7032 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7033 generate_ebd = OMX_FALSE;
7034 }
7035
Arun Menon906de572013-06-18 17:01:40 -07007036 if (nal_length == 0) {
7037 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7038 if (m_frame_parser.parse_sc_frame(psource_frame,
7039 &h264_scratch,&partial_frame) == -1) {
7040 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007041 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007042 }
Arun Menon906de572013-06-18 17:01:40 -07007043 } else {
7044 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7045 if (m_frame_parser.parse_h264_nallength(psource_frame,
7046 &h264_scratch,&partial_frame) == -1) {
7047 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7048 return OMX_ErrorBadParameter;
7049 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007050 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007051
Arun Menon906de572013-06-18 17:01:40 -07007052 if (partial_frame == 0) {
7053 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
7054 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7055 nal_count++;
7056 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7057 h264_scratch.nFlags = psource_frame->nFlags;
7058 } else {
7059 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
7060 if (h264_scratch.nFilledLen) {
7061 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7062 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007063#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007064 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7065 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7066 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7067 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7068 // If timeinfo is present frame info from SEI is already processed
7069 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7070 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007071#endif
Arun Menon906de572013-06-18 17:01:40 -07007072 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7073 nal_count++;
7074 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7075 pdest_frame->nTimeStamp = h264_last_au_ts;
7076 pdest_frame->nFlags = h264_last_au_flags;
7077#ifdef PANSCAN_HDLR
7078 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7079 h264_parser->update_panscan_data(h264_last_au_ts);
7080#endif
7081 }
7082 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7083 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7084 h264_last_au_ts = h264_scratch.nTimeStamp;
7085 h264_last_au_flags = h264_scratch.nFlags;
7086#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7087 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7088 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7089 if (!VALID_TS(h264_last_au_ts))
7090 h264_last_au_ts = ts_in_sei;
7091 }
7092#endif
7093 } else
7094 h264_last_au_ts = LLONG_MAX;
7095 }
7096
7097 if (!isNewFrame) {
7098 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7099 h264_scratch.nFilledLen) {
7100 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
7101 h264_scratch.nFilledLen);
7102 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7103 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7104 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7105 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7106 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7107 h264_scratch.nFilledLen = 0;
7108 } else {
7109 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7110 return OMX_ErrorBadParameter;
7111 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007112 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007113 look_ahead_nal = true;
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05307114 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007115 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7116 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
7117 pdest_frame->nFilledLen,frame_count++);
7118
7119 if (pdest_frame->nFilledLen == 0) {
7120 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7121 look_ahead_nal = false;
7122 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7123 h264_scratch.nFilledLen) {
7124 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7125 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7126 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7127 h264_scratch.nFilledLen = 0;
7128 } else {
7129 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7130 return OMX_ErrorBadParameter;
7131 }
7132 } else {
7133 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
7134 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7135 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7136 }
7137 /*Push the frame to the Decoder*/
7138 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7139 return OMX_ErrorBadParameter;
7140 }
7141 //frame_count++;
7142 pdest_frame = NULL;
7143 if (m_input_free_q.m_size) {
7144 m_input_free_q.pop_entry(&address,&p2,&id);
7145 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7146 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7147 pdest_frame->nFilledLen = 0;
7148 pdest_frame->nFlags = 0;
7149 pdest_frame->nTimeStamp = LLONG_MAX;
7150 }
7151 }
7152 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007153 }
Arun Menon906de572013-06-18 17:01:40 -07007154 } else {
7155 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
7156 /*Check if Destination Buffer is full*/
7157 if (h264_scratch.nAllocLen ==
7158 h264_scratch.nFilledLen + h264_scratch.nOffset) {
7159 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7160 return OMX_ErrorStreamCorrupt;
7161 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007162 }
Arun Menon906de572013-06-18 17:01:40 -07007163
7164 if (!psource_frame->nFilledLen) {
7165 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7166
7167 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7168 if (pdest_frame) {
7169 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7170 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7171 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007172 if(pdest_frame->nFilledLen == 0) {
7173 /* No residual frame from before, send whatever
7174 * we have left */
7175 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7176 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7177 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7178 h264_scratch.nFilledLen = 0;
7179 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7180 } else {
7181 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7182 if(!isNewFrame) {
7183 /* Have a residual frame, but we know that the
7184 * AU in this frame is belonging to whatever
7185 * frame we had left over. So append it */
7186 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7187 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7188 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7189 h264_scratch.nFilledLen = 0;
7190 pdest_frame->nTimeStamp = h264_last_au_ts;
7191 } else {
7192 /* Completely new frame, let's just push what
7193 * we have now. The resulting EBD would trigger
7194 * another push */
7195 generate_ebd = OMX_FALSE;
7196 pdest_frame->nTimeStamp = h264_last_au_ts;
7197 h264_last_au_ts = h264_scratch.nTimeStamp;
7198 }
7199 }
Arun Menon906de572013-06-18 17:01:40 -07007200 } else {
7201 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7202 return OMX_ErrorBadParameter;
7203 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007204
7205 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7206 if(generate_ebd == OMX_TRUE) {
7207 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7208 }
Arun Menon906de572013-06-18 17:01:40 -07007209
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05307210 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007211 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7212 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7213#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7214 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7215 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7216 if (!VALID_TS(pdest_frame->nTimeStamp))
7217 pdest_frame->nTimeStamp = ts_in_sei;
7218 }
7219#endif
7220 /*Push the frame to the Decoder*/
7221 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7222 return OMX_ErrorBadParameter;
7223 }
7224 frame_count++;
7225 pdest_frame = NULL;
7226 } else {
7227 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
7228 pdest_frame,h264_scratch.nFilledLen);
7229 generate_ebd = OMX_FALSE;
7230 }
7231 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007232 }
Arun Menon906de572013-06-18 17:01:40 -07007233 if (generate_ebd && !psource_frame->nFilledLen) {
7234 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7235 psource_frame = NULL;
7236 if (m_input_pending_q.m_size) {
7237 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7238 m_input_pending_q.pop_entry(&address,&p2,&id);
7239 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7240 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
7241 psource_frame->nFlags,psource_frame->nFilledLen);
7242 }
7243 }
7244 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007245}
7246
7247OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7248{
7249 OMX_U8 *buf, *pdest;
7250 OMX_U32 partial_frame = 1;
7251 OMX_U32 buf_len, dest_len;
7252
Arun Menon906de572013-06-18 17:01:40 -07007253 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007254 first_frame = 1;
7255 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
Arun Menon906de572013-06-18 17:01:40 -07007256 if (!m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007257 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7258 buf = psource_frame->pBuffer;
7259 buf_len = psource_frame->nFilledLen;
7260
7261 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007262 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007263 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007264 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007265 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007266 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007267 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7268 return OMX_ErrorStreamCorrupt;
7269 }
Arun Menon906de572013-06-18 17:01:40 -07007270 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007271 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7272 pdest_frame->nOffset;
7273 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007274 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007275
Arun Menon906de572013-06-18 17:01:40 -07007276 if (dest_len < m_vendor_config.nDataSize) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007277 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7278 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007279 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007280 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7281 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7282 }
7283 }
7284 }
7285
Arun Menon906de572013-06-18 17:01:40 -07007286 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007287 case VC1_AP:
7288 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007289 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007290 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7291 return OMX_ErrorBadParameter;
7292 }
Arun Menon906de572013-06-18 17:01:40 -07007293 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007294
7295 case VC1_SP_MP_RCV:
7296 default:
7297 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7298 return OMX_ErrorBadParameter;
7299 }
7300 return OMX_ErrorNone;
7301}
7302
David Ng38e2d232013-03-15 20:05:58 -07007303#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007304bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007305 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007306{
Arun Menon906de572013-06-18 17:01:40 -07007307 struct pmem_allocation allocation;
7308 allocation.size = buffer_size;
7309 allocation.align = clip2(alignment);
7310 if (allocation.align < 4096) {
7311 allocation.align = 4096;
7312 }
7313 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
7314 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7315 allocation.align, allocation.size);
7316 return false;
7317 }
7318 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007319}
David Ng38e2d232013-03-15 20:05:58 -07007320#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007321#ifdef USE_ION
7322int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007323 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7324 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007325{
Arun Menon906de572013-06-18 17:01:40 -07007326 int fd = -EINVAL;
7327 int rc = -EINVAL;
7328 int ion_dev_flag;
7329 struct vdec_ion ion_buf_info;
7330 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7331 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7332 return -EINVAL;
7333 }
7334 ion_dev_flag = O_RDONLY;
7335 fd = open (MEM_DEVICE, ion_dev_flag);
7336 if (fd < 0) {
7337 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7338 return fd;
7339 }
7340 alloc_data->flags = 0;
7341 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7342 alloc_data->flags |= ION_FLAG_CACHED;
7343 }
7344 alloc_data->len = buffer_size;
7345 alloc_data->align = clip2(alignment);
7346 if (alloc_data->align < 4096) {
7347 alloc_data->align = 4096;
7348 }
7349 if ((secure_mode) && (flag & ION_SECURE))
7350 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007351
Arun Menon906de572013-06-18 17:01:40 -07007352 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7353 if (secure_mode)
7354 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7355 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7356 if (rc || !alloc_data->handle) {
7357 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7358 alloc_data->handle = NULL;
7359 close(fd);
7360 fd = -ENOMEM;
7361 return fd;
7362 }
7363 fd_data->handle = alloc_data->handle;
7364 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7365 if (rc) {
7366 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7367 ion_buf_info.ion_alloc_data = *alloc_data;
7368 ion_buf_info.ion_device_fd = fd;
7369 ion_buf_info.fd_ion_data = *fd_data;
7370 free_ion_memory(&ion_buf_info);
7371 fd_data->fd =-1;
7372 close(fd);
7373 fd = -ENOMEM;
7374 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007375
Arun Menon906de572013-06-18 17:01:40 -07007376 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007377}
7378
Arun Menon906de572013-06-18 17:01:40 -07007379void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7380{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007381
Arun Menon906de572013-06-18 17:01:40 -07007382 if (!buf_ion_info) {
7383 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7384 return;
7385 }
7386 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7387 &buf_ion_info->ion_alloc_data.handle)) {
7388 DEBUG_PRINT_ERROR("\n ION: free failed" );
7389 }
7390 close(buf_ion_info->ion_device_fd);
7391 buf_ion_info->ion_device_fd = -1;
7392 buf_ion_info->ion_alloc_data.handle = NULL;
7393 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007394}
7395#endif
7396void omx_vdec::free_output_buffer_header()
7397{
Arun Menon906de572013-06-18 17:01:40 -07007398 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7399 output_use_buffer = false;
7400 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007401
Arun Menon906de572013-06-18 17:01:40 -07007402 if (m_out_mem_ptr) {
7403 free (m_out_mem_ptr);
7404 m_out_mem_ptr = NULL;
7405 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007406
Arun Menon906de572013-06-18 17:01:40 -07007407 if (m_platform_list) {
7408 free(m_platform_list);
7409 m_platform_list = NULL;
7410 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007411
Arun Menon906de572013-06-18 17:01:40 -07007412 if (drv_ctx.ptr_respbuffer) {
7413 free (drv_ctx.ptr_respbuffer);
7414 drv_ctx.ptr_respbuffer = NULL;
7415 }
7416 if (drv_ctx.ptr_outputbuffer) {
7417 free (drv_ctx.ptr_outputbuffer);
7418 drv_ctx.ptr_outputbuffer = NULL;
7419 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007420#ifdef USE_ION
7421 if (drv_ctx.op_buf_ion_info) {
7422 DEBUG_PRINT_LOW("\n Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007423 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007424 drv_ctx.op_buf_ion_info = NULL;
7425 }
7426#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007427#ifdef META_DATA_MODE_SUPPORTED
7428 if (out_dynamic_list) {
7429 free(out_dynamic_list);
7430 out_dynamic_list = NULL;
7431 }
7432#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007433}
7434
7435void omx_vdec::free_input_buffer_header()
7436{
7437 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007438 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007439 if (m_inp_heap_ptr) {
7440 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7441 free (m_inp_heap_ptr);
7442 m_inp_heap_ptr = NULL;
7443 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007444
Arun Menon906de572013-06-18 17:01:40 -07007445 if (m_phdr_pmem_ptr) {
7446 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7447 free (m_phdr_pmem_ptr);
7448 m_phdr_pmem_ptr = NULL;
7449 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007450 }
Arun Menon906de572013-06-18 17:01:40 -07007451 if (m_inp_mem_ptr) {
7452 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7453 free (m_inp_mem_ptr);
7454 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007455 }
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007456 /* We just freed all the buffer headers, every thing in m_input_free_q
7457 * is now invalid */
7458 while (m_input_free_q.m_size) {
7459 unsigned address, p2, id;
7460 m_input_free_q.pop_entry(&address, &p2, &id);
7461 }
Arun Menon906de572013-06-18 17:01:40 -07007462 if (drv_ctx.ptr_inputbuffer) {
7463 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7464 free (drv_ctx.ptr_inputbuffer);
7465 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007466 }
7467#ifdef USE_ION
7468 if (drv_ctx.ip_buf_ion_info) {
7469 DEBUG_PRINT_LOW("\n Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007470 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007471 drv_ctx.ip_buf_ion_info = NULL;
7472 }
7473#endif
7474}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007475
7476int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007477{
Arun Menon906de572013-06-18 17:01:40 -07007478 enum v4l2_buf_type btype;
7479 int rc = 0;
7480 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007481
Arun Menon906de572013-06-18 17:01:40 -07007482 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7483 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7484 v4l2_port = OUTPUT_PORT;
7485 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7486 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7487 v4l2_port = CAPTURE_PORT;
7488 } else if (port == OMX_ALL) {
7489 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7490 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007491
Arun Menon906de572013-06-18 17:01:40 -07007492 if (!rc_input)
7493 return rc_input;
7494 else
7495 return rc_output;
7496 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007497
Arun Menon906de572013-06-18 17:01:40 -07007498 if (!streaming[v4l2_port]) {
7499 // already streamed off, warn and move on
7500 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7501 " which is already streamed off", v4l2_port);
7502 return 0;
7503 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007504
Arun Menon906de572013-06-18 17:01:40 -07007505 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007506
Arun Menon906de572013-06-18 17:01:40 -07007507 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7508 if (rc) {
7509 /*TODO: How to handle this case */
7510 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
7511 } else {
7512 streaming[v4l2_port] = false;
7513 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007514
Arun Menon906de572013-06-18 17:01:40 -07007515 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007516}
7517
7518OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7519{
Arun Menon906de572013-06-18 17:01:40 -07007520 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7521 struct v4l2_requestbuffers bufreq;
7522 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7523 struct v4l2_format fmt;
7524 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007525 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007526 buffer_prop->actualcount, buffer_prop->buffer_size);
7527 bufreq.memory = V4L2_MEMORY_USERPTR;
7528 bufreq.count = 1;
7529 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7530 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7531 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7532 fmt.fmt.pix_mp.pixelformat = output_capability;
7533 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7534 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7535 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7536 fmt.fmt.pix_mp.pixelformat = capture_capability;
7537 } else {
7538 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007539 }
Arun Menon906de572013-06-18 17:01:40 -07007540 if (eRet==OMX_ErrorNone) {
7541 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007542 }
Arun Menon906de572013-06-18 17:01:40 -07007543 if (ret) {
7544 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7545 /*TODO: How to handle this case */
7546 eRet = OMX_ErrorInsufficientResources;
7547 return eRet;
7548 } else {
7549 buffer_prop->actualcount = bufreq.count;
7550 buffer_prop->mincount = bufreq.count;
7551 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007552 }
Arun Menon906de572013-06-18 17:01:40 -07007553 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7554 buffer_prop->actualcount, buffer_prop->buffer_size);
7555
7556 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7557 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7558
7559 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7560
7561 update_resolution(fmt.fmt.pix_mp.width,
7562 fmt.fmt.pix_mp.height,
7563 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7564 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7565 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7566 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
7567 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
7568
7569 if (ret) {
7570 /*TODO: How to handle this case */
7571 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7572 eRet = OMX_ErrorInsufficientResources;
7573 } else {
7574 int extra_idx = 0;
7575
7576 eRet = is_video_session_supported();
7577 if (eRet)
7578 return eRet;
7579
7580 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7581 buf_size = buffer_prop->buffer_size;
7582 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7583 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7584 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7585 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7586 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7587 return OMX_ErrorBadParameter;
7588 }
7589 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7590 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7591 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7592 }
7593 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7594 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7595 }
7596 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7597 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7598 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7599 client_extra_data_size);
7600 }
7601 if (client_extra_data_size) {
7602 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7603 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7604 }
7605 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7606 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7607 drv_ctx.extradata_info.buffer_size = extra_data_size;
7608 buf_size += client_extra_data_size;
7609 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7610 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7611 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7612 if (in_reconfig) // BufReq will be set to driver when port is disabled
7613 buffer_prop->buffer_size = buf_size;
7614 else if (buf_size != buffer_prop->buffer_size) {
7615 buffer_prop->buffer_size = buf_size;
7616 eRet = set_buffer_req(buffer_prop);
7617 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007618 }
Arun Menon906de572013-06-18 17:01:40 -07007619 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7620 buffer_prop->actualcount, buffer_prop->buffer_size);
7621 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007622}
7623
7624OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7625{
Arun Menon906de572013-06-18 17:01:40 -07007626 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7627 unsigned buf_size = 0;
7628 struct v4l2_format fmt;
7629 struct v4l2_requestbuffers bufreq;
7630 int ret;
7631 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7632 buffer_prop->actualcount, buffer_prop->buffer_size);
7633 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7634 if (buf_size != buffer_prop->buffer_size) {
7635 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7636 buffer_prop->buffer_size, buf_size);
7637 eRet = OMX_ErrorBadParameter;
7638 } else {
7639 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7640 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007641
Arun Menon906de572013-06-18 17:01:40 -07007642 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7643 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7644 fmt.fmt.pix_mp.pixelformat = output_capability;
7645 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7646 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7647 fmt.fmt.pix_mp.pixelformat = capture_capability;
7648 } else {
7649 eRet = OMX_ErrorBadParameter;
7650 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007651
Arun Menon906de572013-06-18 17:01:40 -07007652 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7653 if (ret) {
7654 /*TODO: How to handle this case */
7655 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7656 eRet = OMX_ErrorInsufficientResources;
7657 }
7658
7659 bufreq.memory = V4L2_MEMORY_USERPTR;
7660 bufreq.count = buffer_prop->actualcount;
7661 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7662 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7663 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7664 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7665 } else {
7666 eRet = OMX_ErrorBadParameter;
7667 }
7668
7669 if (eRet==OMX_ErrorNone) {
7670 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7671 }
7672
7673 if (ret) {
7674 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7675 /*TODO: How to handle this case */
7676 eRet = OMX_ErrorInsufficientResources;
7677 } else if (bufreq.count < buffer_prop->actualcount) {
7678 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7679 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7680 buffer_prop->actualcount, bufreq.count);
7681 eRet = OMX_ErrorInsufficientResources;
7682 } else {
7683 if (!client_buffers.update_buffer_req()) {
7684 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7685 eRet = OMX_ErrorInsufficientResources;
7686 }
7687 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007688 }
Arun Menon906de572013-06-18 17:01:40 -07007689 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007690}
7691
Shalaj Jain273b3e02012-06-22 19:08:03 -07007692OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7693{
Arun Menon906de572013-06-18 17:01:40 -07007694 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7695 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007696}
7697
7698OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7699{
Arun Menon906de572013-06-18 17:01:40 -07007700 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7701 if (!portDefn) {
7702 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007703 }
Arun Menon906de572013-06-18 17:01:40 -07007704 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
7705 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7706 portDefn->nSize = sizeof(portDefn);
7707 portDefn->eDomain = OMX_PortDomainVideo;
7708 if (drv_ctx.frame_rate.fps_denominator > 0)
7709 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7710 drv_ctx.frame_rate.fps_denominator;
7711 else {
7712 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7713 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007714 }
Arun Menon906de572013-06-18 17:01:40 -07007715 if (0 == portDefn->nPortIndex) {
7716 portDefn->eDir = OMX_DirInput;
7717 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7718 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7719 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7720 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7721 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7722 portDefn->bEnabled = m_inp_bEnabled;
7723 portDefn->bPopulated = m_inp_bPopulated;
7724 } else if (1 == portDefn->nPortIndex) {
7725 unsigned int buf_size = 0;
7726 if (!client_buffers.update_buffer_req()) {
7727 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
7728 return OMX_ErrorHardware;
7729 }
7730 if (!client_buffers.get_buffer_req(buf_size)) {
7731 DEBUG_PRINT_ERROR("\n update buffer requirements");
7732 return OMX_ErrorHardware;
7733 }
7734 portDefn->nBufferSize = buf_size;
7735 portDefn->eDir = OMX_DirOutput;
7736 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7737 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7738 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7739 portDefn->bEnabled = m_out_bEnabled;
7740 portDefn->bPopulated = m_out_bPopulated;
7741 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
7742 DEBUG_PRINT_ERROR("\n Error in getting color format");
7743 return OMX_ErrorHardware;
7744 }
7745 } else {
7746 portDefn->eDir = OMX_DirMax;
7747 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7748 (int)portDefn->nPortIndex);
7749 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007750 }
Arun Menon906de572013-06-18 17:01:40 -07007751 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7752 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7753 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7754 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7755 DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
7756 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
7757 portDefn->format.video.nFrameHeight,
7758 portDefn->format.video.nStride,
7759 portDefn->format.video.nSliceHeight);
7760 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007761
7762}
7763
7764OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7765{
Arun Menon906de572013-06-18 17:01:40 -07007766 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7767 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7768 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007769
Arun Menon906de572013-06-18 17:01:40 -07007770 if (!m_out_mem_ptr) {
7771 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
7772 int nBufHdrSize = 0;
7773 int nPlatformEntrySize = 0;
7774 int nPlatformListSize = 0;
7775 int nPMEMInfoSize = 0;
7776 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7777 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7778 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007779
Arun Menon906de572013-06-18 17:01:40 -07007780 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
7781 drv_ctx.op_buf.actualcount);
7782 nBufHdrSize = drv_ctx.op_buf.actualcount *
7783 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007784
Arun Menon906de572013-06-18 17:01:40 -07007785 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7786 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7787 nPlatformListSize = drv_ctx.op_buf.actualcount *
7788 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7789 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7790 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007791
Arun Menon906de572013-06-18 17:01:40 -07007792 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
7793 sizeof(OMX_BUFFERHEADERTYPE),
7794 nPMEMInfoSize,
7795 nPlatformListSize);
7796 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
7797 m_out_bm_count);
7798 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7799 // Alloc mem for platform specific info
7800 char *pPtr=NULL;
7801 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7802 nPMEMInfoSize,1);
7803 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7804 calloc (sizeof(struct vdec_bufferpayload),
7805 drv_ctx.op_buf.actualcount);
7806 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7807 calloc (sizeof (struct vdec_output_frameinfo),
7808 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007809#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007810 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7811 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007812#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007813#ifdef META_DATA_MODE_SUPPORTED
7814 if (dynamic_buf_mode) {
7815 out_dynamic_list = (struct dynamic_buf_list *) \
7816 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
7817 }
7818#endif
Arun Menon906de572013-06-18 17:01:40 -07007819 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7820 && drv_ctx.ptr_respbuffer) {
7821 bufHdr = m_out_mem_ptr;
7822 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7823 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7824 (((char *) m_platform_list) + nPlatformListSize);
7825 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7826 (((char *) m_platform_entry) + nPlatformEntrySize);
7827 pPlatformList = m_platform_list;
7828 pPlatformEntry = m_platform_entry;
7829 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007830
Arun Menon906de572013-06-18 17:01:40 -07007831 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007832
Arun Menon906de572013-06-18 17:01:40 -07007833 // Settting the entire storage nicely
7834 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
7835 m_out_mem_ptr,pPlatformEntry);
7836 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
7837 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7838 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7839 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7840 // Set the values when we determine the right HxW param
7841 bufHdr->nAllocLen = 0;
7842 bufHdr->nFilledLen = 0;
7843 bufHdr->pAppPrivate = NULL;
7844 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7845 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7846 pPlatformEntry->entry = pPMEMInfo;
7847 // Initialize the Platform List
7848 pPlatformList->nEntries = 1;
7849 pPlatformList->entryList = pPlatformEntry;
7850 // Keep pBuffer NULL till vdec is opened
7851 bufHdr->pBuffer = NULL;
7852 pPMEMInfo->offset = 0;
7853 pPMEMInfo->pmem_fd = 0;
7854 bufHdr->pPlatformPrivate = pPlatformList;
7855 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007856#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007857 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007858#endif
Arun Menon906de572013-06-18 17:01:40 -07007859 /*Create a mapping between buffers*/
7860 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7861 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7862 &drv_ctx.ptr_outputbuffer[i];
7863 // Move the buffer and buffer header pointers
7864 bufHdr++;
7865 pPMEMInfo++;
7866 pPlatformEntry++;
7867 pPlatformList++;
7868 }
7869 } else {
7870 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
7871 m_out_mem_ptr, pPtr);
7872 if (m_out_mem_ptr) {
7873 free(m_out_mem_ptr);
7874 m_out_mem_ptr = NULL;
7875 }
7876 if (pPtr) {
7877 free(pPtr);
7878 pPtr = NULL;
7879 }
7880 if (drv_ctx.ptr_outputbuffer) {
7881 free(drv_ctx.ptr_outputbuffer);
7882 drv_ctx.ptr_outputbuffer = NULL;
7883 }
7884 if (drv_ctx.ptr_respbuffer) {
7885 free(drv_ctx.ptr_respbuffer);
7886 drv_ctx.ptr_respbuffer = NULL;
7887 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007888#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007889 if (drv_ctx.op_buf_ion_info) {
7890 DEBUG_PRINT_LOW("\n Free o/p ion context");
7891 free(drv_ctx.op_buf_ion_info);
7892 drv_ctx.op_buf_ion_info = NULL;
7893 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007894#endif
Arun Menon906de572013-06-18 17:01:40 -07007895 eRet = OMX_ErrorInsufficientResources;
7896 }
7897 } else {
7898 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007899 }
Arun Menon906de572013-06-18 17:01:40 -07007900 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007901}
7902
7903void omx_vdec::complete_pending_buffer_done_cbs()
7904{
Arun Menon906de572013-06-18 17:01:40 -07007905 unsigned p1;
7906 unsigned p2;
7907 unsigned ident;
7908 omx_cmd_queue tmp_q, pending_bd_q;
7909 pthread_mutex_lock(&m_lock);
7910 // pop all pending GENERATE FDB from ftb queue
7911 while (m_ftb_q.m_size) {
7912 m_ftb_q.pop_entry(&p1,&p2,&ident);
7913 if (ident == OMX_COMPONENT_GENERATE_FBD) {
7914 pending_bd_q.insert_entry(p1,p2,ident);
7915 } else {
7916 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007917 }
Arun Menon906de572013-06-18 17:01:40 -07007918 }
7919 //return all non GENERATE FDB to ftb queue
7920 while (tmp_q.m_size) {
7921 tmp_q.pop_entry(&p1,&p2,&ident);
7922 m_ftb_q.insert_entry(p1,p2,ident);
7923 }
7924 // pop all pending GENERATE EDB from etb queue
7925 while (m_etb_q.m_size) {
7926 m_etb_q.pop_entry(&p1,&p2,&ident);
7927 if (ident == OMX_COMPONENT_GENERATE_EBD) {
7928 pending_bd_q.insert_entry(p1,p2,ident);
7929 } else {
7930 tmp_q.insert_entry(p1,p2,ident);
7931 }
7932 }
7933 //return all non GENERATE FDB to etb queue
7934 while (tmp_q.m_size) {
7935 tmp_q.pop_entry(&p1,&p2,&ident);
7936 m_etb_q.insert_entry(p1,p2,ident);
7937 }
7938 pthread_mutex_unlock(&m_lock);
7939 // process all pending buffer dones
7940 while (pending_bd_q.m_size) {
7941 pending_bd_q.pop_entry(&p1,&p2,&ident);
7942 switch (ident) {
7943 case OMX_COMPONENT_GENERATE_EBD:
7944 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
7945 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
7946 omx_report_error ();
7947 }
7948 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007949
Arun Menon906de572013-06-18 17:01:40 -07007950 case OMX_COMPONENT_GENERATE_FBD:
7951 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
7952 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
7953 omx_report_error ();
7954 }
7955 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007956 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007957 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007958}
7959
7960void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
7961{
Arun Menon906de572013-06-18 17:01:40 -07007962 OMX_U32 new_frame_interval = 0;
7963 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
7964 && llabs(act_timestamp - prev_ts) > 2000) {
7965 new_frame_interval = client_set_fps ? frm_int :
7966 llabs(act_timestamp - prev_ts);
7967 if (new_frame_interval < frm_int || frm_int == 0) {
7968 frm_int = new_frame_interval;
7969 if (frm_int) {
7970 drv_ctx.frame_rate.fps_numerator = 1e6;
7971 drv_ctx.frame_rate.fps_denominator = frm_int;
7972 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
7973 frm_int, drv_ctx.frame_rate.fps_numerator /
7974 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007975
Arun Menon906de572013-06-18 17:01:40 -07007976 /* We need to report the difference between this FBD and the previous FBD
7977 * back to the driver for clock scaling purposes. */
7978 struct v4l2_outputparm oparm;
7979 /*XXX: we're providing timing info as seconds per frame rather than frames
7980 * per second.*/
7981 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
7982 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007983
Arun Menon906de572013-06-18 17:01:40 -07007984 struct v4l2_streamparm sparm;
7985 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7986 sparm.parm.output = oparm;
7987 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
7988 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
7989 performance might be affected");
7990 }
7991
7992 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007993 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007994 }
Arun Menon906de572013-06-18 17:01:40 -07007995 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007996}
7997
7998void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
7999{
Arun Menon906de572013-06-18 17:01:40 -07008000 if (rst_prev_ts && VALID_TS(act_timestamp)) {
8001 prev_ts = act_timestamp;
8002 rst_prev_ts = false;
8003 } else if (VALID_TS(prev_ts)) {
8004 bool codec_cond = (drv_ctx.timestamp_adjust)?
8005 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8006 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8007 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8008 if (frm_int > 0 && codec_cond) {
8009 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8010 act_timestamp = prev_ts + frm_int;
8011 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8012 prev_ts = act_timestamp;
8013 } else
8014 set_frame_rate(act_timestamp);
8015 } else if (frm_int > 0) // In this case the frame rate was set along
8016 { // with the port definition, start ts with 0
8017 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8018 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008019 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008020}
8021
8022void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8023{
Arun Menon906de572013-06-18 17:01:40 -07008024 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8025 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308026 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008027 OMX_U32 frame_rate = 0;
8028 int consumed_len = 0;
8029 OMX_U32 num_MB_in_frame;
8030 OMX_U32 recovery_sei_flags = 1;
8031 int enable = 0;
8032 OMX_U32 mbaff = 0;
8033 int buf_index = p_buf_hdr - m_out_mem_ptr;
8034 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8035 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8036 p_buf_hdr->nOffset;
8037 if (!drv_ctx.extradata_info.uaddr) {
8038 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008039 }
Arun Menon906de572013-06-18 17:01:40 -07008040 p_extra = (OMX_OTHER_EXTRADATATYPE *)
8041 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8042 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8043 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
8044 p_extra = NULL;
8045 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
8046 if (data) {
8047 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8048 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
8049 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
8050 DEBUG_PRINT_LOW("Invalid extra data size");
8051 break;
8052 }
8053 switch ((unsigned long)data->eType) {
8054 case EXTRADATA_INTERLACE_VIDEO:
8055 struct msm_vidc_interlace_payload *payload;
8056 payload = (struct msm_vidc_interlace_payload *)data->data;
8057 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8058 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8059 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008060 else if (payload && (payload->format == INTERLACE_FRAME_TOPFIELDFIRST ||
8061 payload->format == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8062 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8063 enable = 1;
8064 } else {
Arun Menon906de572013-06-18 17:01:40 -07008065 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8066 enable = 1;
8067 }
8068 if (m_enable_android_native_buffers)
8069 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8070 PP_PARAM_INTERLACED, (void*)&enable);
8071 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8072 append_interlace_extradata(p_extra, payload->format);
8073 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8074 }
8075 break;
8076 case EXTRADATA_FRAME_RATE:
8077 struct msm_vidc_framerate_payload *frame_rate_payload;
8078 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8079 frame_rate = frame_rate_payload->frame_rate;
8080 break;
8081 case EXTRADATA_TIMESTAMP:
8082 struct msm_vidc_ts_payload *time_stamp_payload;
8083 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308084 time_stamp = time_stamp_payload->timestamp_lo;
8085 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8086 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008087 break;
8088 case EXTRADATA_NUM_CONCEALED_MB:
8089 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8090 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8091 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8092 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8093 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8094 break;
8095 case EXTRADATA_INDEX:
8096 int *etype;
8097 etype = (int *)(data->data);
8098 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8099 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8100 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8101 if (aspect_ratio_payload) {
8102 ((struct vdec_output_frameinfo *)
8103 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8104 ((struct vdec_output_frameinfo *)
8105 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8106 }
8107 }
8108 break;
8109 case EXTRADATA_RECOVERY_POINT_SEI:
8110 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8111 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8112 recovery_sei_flags = recovery_sei_payload->flags;
8113 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8114 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
8115 DEBUG_PRINT_HIGH("\n");
8116 DEBUG_PRINT_HIGH("***************************************************\n");
8117 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
8118 DEBUG_PRINT_HIGH("***************************************************\n");
8119 }
8120 break;
8121 case EXTRADATA_PANSCAN_WINDOW:
8122 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8123 break;
8124 case EXTRADATA_MPEG2_SEQDISP:
8125 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8126 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8127 if (seqdisp_payload) {
8128 m_disp_hor_size = seqdisp_payload->disp_width;
8129 m_disp_vert_size = seqdisp_payload->disp_height;
8130 }
8131 break;
8132 default:
8133 goto unrecognized_extradata;
8134 }
8135 consumed_len += data->nSize;
8136 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8137 }
8138 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8139 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8140 append_frame_info_extradata(p_extra,
8141 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308142 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008143 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008144 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
Arun Menon906de572013-06-18 17:01:40 -07008145 }
8146 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008147unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07008148 if (!secure_mode && client_extradata)
8149 append_terminator_extradata(p_extra);
8150 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008151}
8152
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008153OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008154 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008155{
Arun Menon906de572013-06-18 17:01:40 -07008156 OMX_ERRORTYPE ret = OMX_ErrorNone;
8157 struct v4l2_control control;
8158 if (m_state != OMX_StateLoaded) {
8159 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8160 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008161 }
Arun Menon906de572013-06-18 17:01:40 -07008162 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
8163 client_extradata, requested_extradata, enable, is_internal);
8164
8165 if (!is_internal) {
8166 if (enable)
8167 client_extradata |= requested_extradata;
8168 else
8169 client_extradata = client_extradata & ~requested_extradata;
8170 }
8171
8172 if (enable) {
8173 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8174 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8175 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8176 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8177 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8178 " Quality of interlaced clips might be impacted.\n");
8179 }
8180 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
8181 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8182 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8183 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8184 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8185 }
8186 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8187 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8188 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8189 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8190 }
8191 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8192 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8193 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8194 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8195 }
8196 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8197 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8198 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8199 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8200 }
8201 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8202 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8203 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8204 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8205 }
8206 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8207 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8208 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8209 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8210 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8211 }
8212 }
8213 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
8214 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8215 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8216 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8217 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8218 }
8219 }
8220 }
8221 ret = get_buffer_req(&drv_ctx.op_buf);
8222 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008223}
8224
8225OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8226{
Arun Menon906de572013-06-18 17:01:40 -07008227 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8228 OMX_U8 *data_ptr = extra->data, data = 0;
8229 while (byte_count < extra->nDataSize) {
8230 data = *data_ptr;
8231 while (data) {
8232 num_MB += (data&0x01);
8233 data >>= 1;
8234 }
8235 data_ptr++;
8236 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008237 }
Arun Menon906de572013-06-18 17:01:40 -07008238 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8239 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8240 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008241}
8242
8243void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8244{
Arun Menon906de572013-06-18 17:01:40 -07008245 if (!m_debug_extradata)
8246 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008247
8248 DEBUG_PRINT_HIGH(
Arun Menon906de572013-06-18 17:01:40 -07008249 "============== Extra Data ==============\n"
8250 " Size: %lu \n"
8251 " Version: %lu \n"
8252 " PortIndex: %lu \n"
8253 " Type: %x \n"
8254 " DataSize: %lu \n",
8255 extra->nSize, extra->nVersion.nVersion,
8256 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008257
Arun Menon906de572013-06-18 17:01:40 -07008258 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8259 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8260 DEBUG_PRINT_HIGH(
8261 "------ Interlace Format ------\n"
8262 " Size: %lu \n"
8263 " Version: %lu \n"
8264 " PortIndex: %lu \n"
8265 " Is Interlace Format: %d \n"
8266 " Interlace Formats: %lu \n"
8267 "=========== End of Interlace ===========\n",
8268 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8269 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8270 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8271 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8272
8273 DEBUG_PRINT_HIGH(
8274 "-------- Frame Format --------\n"
8275 " Picture Type: %d \n"
8276 " Interlace Type: %d \n"
8277 " Pan Scan Total Frame Num: %lu \n"
8278 " Concealed Macro Blocks: %lu \n"
8279 " frame rate: %lu \n"
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05308280 " Time Stamp: %llu \n"
Arun Menon906de572013-06-18 17:01:40 -07008281 " Aspect Ratio X: %lu \n"
8282 " Aspect Ratio Y: %lu \n",
8283 fminfo->ePicType,
8284 fminfo->interlaceType,
8285 fminfo->panScan.numWindows,
8286 fminfo->nConcealedMacroblocks,
8287 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308288 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008289 fminfo->aspectRatio.aspectRatioX,
8290 fminfo->aspectRatio.aspectRatioY);
8291
8292 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8293 DEBUG_PRINT_HIGH(
8294 "------------------------------\n"
8295 " Pan Scan Frame Num: %lu \n"
8296 " Rectangle x: %ld \n"
8297 " Rectangle y: %ld \n"
8298 " Rectangle dx: %ld \n"
8299 " Rectangle dy: %ld \n",
8300 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8301 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8302 }
8303
8304 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8305 } else if (extra->eType == OMX_ExtraDataNone) {
8306 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8307 } else {
8308 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008309 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008310}
8311
8312void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008313 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008314{
Arun Menon906de572013-06-18 17:01:40 -07008315 OMX_STREAMINTERLACEFORMAT *interlace_format;
8316 OMX_U32 mbaff = 0;
8317 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8318 return;
8319 }
8320 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8321 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8322 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8323 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8324 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8325 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8326 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8327 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8328 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8329 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8330 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8331 interlace_format->bInterlaceFormat = OMX_FALSE;
8332 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8333 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Praneeth Paladugudd29c282013-09-12 15:41:47 -07008334 } else if ((interlaced_format_type == INTERLACE_FRAME_TOPFIELDFIRST) && !mbaff) {
8335 interlace_format->bInterlaceFormat = OMX_TRUE;
8336 interlace_format->nInterlaceFormats = OMX_InterlaceFrameTopFieldFirst;
8337 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8338 } else if ((interlaced_format_type == INTERLACE_FRAME_BOTTOMFIELDFIRST) && !mbaff) {
8339 interlace_format->bInterlaceFormat = OMX_TRUE;
8340 interlace_format->nInterlaceFormats = OMX_InterlaceFrameBottomFieldFirst;
8341 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
Arun Menon906de572013-06-18 17:01:40 -07008342 } else {
8343 interlace_format->bInterlaceFormat = OMX_TRUE;
8344 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8345 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8346 }
8347 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008348}
8349
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008350void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008351 struct vdec_aspectratioinfo *aspect_ratio_info,
8352 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008353{
Arun Menon906de572013-06-18 17:01:40 -07008354 m_extradata = frame_info;
8355 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8356 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308357 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008358 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008359}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008360
8361void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008362 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308363 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008364 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008365{
Arun Menon906de572013-06-18 17:01:40 -07008366 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8367 struct msm_vidc_panscan_window *panscan_window;
8368 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008369 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008370 }
Arun Menon906de572013-06-18 17:01:40 -07008371 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8372 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8373 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8374 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8375 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8376 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8377 switch (picture_type) {
8378 case PICTURE_TYPE_I:
8379 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8380 break;
8381 case PICTURE_TYPE_P:
8382 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8383 break;
8384 case PICTURE_TYPE_B:
8385 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8386 break;
8387 default:
8388 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8389 }
8390 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8391 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8392 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8393 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8394 else
8395 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8396 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8397 frame_info->nConcealedMacroblocks = num_conceal_mb;
8398 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308399 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008400 frame_info->panScan.numWindows = 0;
8401 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8402 if (m_disp_hor_size && m_disp_vert_size) {
8403 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8404 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8405 }
8406 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008407
Arun Menon906de572013-06-18 17:01:40 -07008408 if (panscan_payload) {
8409 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8410 panscan_window = &panscan_payload->wnd[0];
8411 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8412 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8413 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8414 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8415 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8416 panscan_window++;
8417 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008418 }
Arun Menon906de572013-06-18 17:01:40 -07008419 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8420 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008421}
8422
8423void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8424{
Arun Menon906de572013-06-18 17:01:40 -07008425 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8426 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8427 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8428 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8429 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8430 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8431 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8432 *portDefn = m_port_def;
8433 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8434 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
8435 portDefn->format.video.nFrameWidth,
8436 portDefn->format.video.nStride,
8437 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008438}
8439
8440void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8441{
Arun Menon906de572013-06-18 17:01:40 -07008442 if (!client_extradata) {
8443 return;
8444 }
8445 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8446 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8447 extra->eType = OMX_ExtraDataNone;
8448 extra->nDataSize = 0;
8449 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008450
Arun Menon906de572013-06-18 17:01:40 -07008451 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008452}
8453
8454OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8455{
Arun Menon906de572013-06-18 17:01:40 -07008456 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8457 if (index >= drv_ctx.ip_buf.actualcount) {
8458 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8459 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008460 }
Arun Menon906de572013-06-18 17:01:40 -07008461 if (m_desc_buffer_ptr == NULL) {
8462 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8463 calloc( (sizeof(desc_buffer_hdr)),
8464 drv_ctx.ip_buf.actualcount);
8465 if (m_desc_buffer_ptr == NULL) {
8466 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8467 return OMX_ErrorInsufficientResources;
8468 }
8469 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008470
Arun Menon906de572013-06-18 17:01:40 -07008471 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8472 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
8473 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8474 return OMX_ErrorInsufficientResources;
8475 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008476
Arun Menon906de572013-06-18 17:01:40 -07008477 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008478}
8479
8480void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8481{
Arun Menon906de572013-06-18 17:01:40 -07008482 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8483 if (m_demux_entries < 8192) {
8484 m_demux_offsets[m_demux_entries++] = address_offset;
8485 }
8486 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008487}
8488
8489void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8490{
Arun Menon906de572013-06-18 17:01:40 -07008491 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8492 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8493 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008494
Arun Menon906de572013-06-18 17:01:40 -07008495 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008496
Arun Menon906de572013-06-18 17:01:40 -07008497 while (index < bytes_to_parse) {
8498 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8499 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8500 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8501 (buf[index+2] == 0x01)) ) {
8502 //Found start code, insert address offset
8503 insert_demux_addr_offset(index);
8504 if (buf[index+2] == 0x01) // 3 byte start code
8505 index += 3;
8506 else //4 byte start code
8507 index += 4;
8508 } else
8509 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008510 }
Arun Menon906de572013-06-18 17:01:40 -07008511 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8512 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008513}
8514
8515OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8516{
Arun Menon906de572013-06-18 17:01:40 -07008517 //fix this, handle 3 byte start code, vc1 terminator entry
8518 OMX_U8 *p_demux_data = NULL;
8519 OMX_U32 desc_data = 0;
8520 OMX_U32 start_addr = 0;
8521 OMX_U32 nal_size = 0;
8522 OMX_U32 suffix_byte = 0;
8523 OMX_U32 demux_index = 0;
8524 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008525
Arun Menon906de572013-06-18 17:01:40 -07008526 if (m_desc_buffer_ptr == NULL) {
8527 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8528 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008529 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008530
Arun Menon906de572013-06-18 17:01:40 -07008531 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8532 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8533 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8534 return OMX_ErrorBadParameter;
8535 }
8536
8537 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8538
8539 if ( ((OMX_U8*)p_demux_data == NULL) ||
8540 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8541 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8542 return OMX_ErrorBadParameter;
8543 } else {
8544 for (; demux_index < m_demux_entries; demux_index++) {
8545 desc_data = 0;
8546 start_addr = m_demux_offsets[demux_index];
8547 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8548 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8549 } else {
8550 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8551 }
8552 if (demux_index < (m_demux_entries - 1)) {
8553 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8554 } else {
8555 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8556 }
8557 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8558 (void *)start_addr,
8559 suffix_byte,
8560 nal_size,
8561 demux_index);
8562 desc_data = (start_addr >> 3) << 1;
8563 desc_data |= (start_addr & 7) << 21;
8564 desc_data |= suffix_byte << 24;
8565
8566 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8567 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8568 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8569 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8570
8571 p_demux_data += 16;
8572 }
8573 if (codec_type_parse == CODEC_TYPE_VC1) {
8574 DEBUG_PRINT_LOW("VC1 terminator entry");
8575 desc_data = 0;
8576 desc_data = 0x82 << 24;
8577 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8578 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8579 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8580 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8581 p_demux_data += 16;
8582 m_demux_entries++;
8583 }
8584 //Add zero word to indicate end of descriptors
8585 memset(p_demux_data, 0, sizeof(OMX_U32));
8586
8587 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8588 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8589 }
8590 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8591 m_demux_entries = 0;
8592 DEBUG_PRINT_LOW("Demux table complete!");
8593 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008594}
8595
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008596OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008597{
Arun Menon906de572013-06-18 17:01:40 -07008598 OMX_ERRORTYPE err = OMX_ErrorNone;
8599 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8600 if (iDivXDrmDecrypt) {
8601 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8602 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008603 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008604 delete iDivXDrmDecrypt;
8605 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008606 }
8607 } else {
8608 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
8609 err = OMX_ErrorUndefined;
8610 }
8611 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008612}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008613
Vinay Kaliada4f4422013-01-09 10:45:03 -08008614omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8615{
Arun Menon906de572013-06-18 17:01:40 -07008616 enabled = false;
8617 omx = NULL;
8618 init_members();
8619 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008620}
8621
8622void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8623{
Arun Menon906de572013-06-18 17:01:40 -07008624 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008625}
8626
Arun Menon906de572013-06-18 17:01:40 -07008627void omx_vdec::allocate_color_convert_buf::init_members()
8628{
8629 allocated_count = 0;
8630 buffer_size_req = 0;
8631 buffer_alignment_req = 0;
8632 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8633 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8634 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8635 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008636#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008637 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008638#endif
Arun Menon906de572013-06-18 17:01:40 -07008639 for (int i = 0; i < MAX_COUNT; i++)
8640 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008641}
8642
Arun Menon906de572013-06-18 17:01:40 -07008643omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8644{
8645 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008646}
8647
8648bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8649{
Arun Menon906de572013-06-18 17:01:40 -07008650 bool status = true;
8651 unsigned int src_size = 0, destination_size = 0;
8652 OMX_COLOR_FORMATTYPE drv_color_format;
8653 if (!omx) {
8654 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8655 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008656 }
Arun Menon906de572013-06-18 17:01:40 -07008657 if (!enabled) {
8658 DEBUG_PRINT_HIGH("\n No color conversion required");
8659 return status;
8660 }
8661 pthread_mutex_lock(&omx->c_lock);
8662 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8663 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8664 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
8665 status = false;
8666 goto fail_update_buf_req;
8667 }
8668 c2d.close();
8669 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8670 omx->drv_ctx.video_resolution.frame_width,
8671 NV12_128m,YCbCr420P);
8672 if (status) {
8673 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8674 if (status)
8675 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8676 }
8677 if (status) {
8678 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8679 !destination_size) {
8680 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
8681 "driver size %d destination size %d",
8682 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8683 status = false;
8684 c2d.close();
8685 buffer_size_req = 0;
8686 } else {
8687 buffer_size_req = destination_size;
8688 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8689 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8690 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8691 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8692 }
8693 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008694fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008695 pthread_mutex_unlock(&omx->c_lock);
8696 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008697}
8698
8699bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008700 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008701{
Arun Menon906de572013-06-18 17:01:40 -07008702 bool status = true;
8703 OMX_COLOR_FORMATTYPE drv_color_format;
8704 if (!omx) {
8705 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8706 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008707 }
Arun Menon906de572013-06-18 17:01:40 -07008708 pthread_mutex_lock(&omx->c_lock);
8709 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8710 drv_color_format = (OMX_COLOR_FORMATTYPE)
8711 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8712 else {
8713 DEBUG_PRINT_ERROR("\n Incorrect color format");
8714 status = false;
8715 }
8716 if (status && (drv_color_format != dest_color_format)) {
8717 DEBUG_PRINT_LOW("Enabling C2D\n");
8718 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
8719 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
8720 status = false;
8721 } else {
8722 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8723 if (enabled)
8724 c2d.destroy();
8725 enabled = false;
8726 if (!c2d.init()) {
8727 DEBUG_PRINT_ERROR("\n open failed for c2d");
8728 status = false;
8729 } else
8730 enabled = true;
8731 }
8732 } else {
8733 if (enabled)
8734 c2d.destroy();
8735 enabled = false;
8736 }
8737 pthread_mutex_unlock(&omx->c_lock);
8738 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008739}
8740
8741OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8742{
Arun Menon906de572013-06-18 17:01:40 -07008743 if (!omx) {
8744 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8745 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008746 }
Arun Menon906de572013-06-18 17:01:40 -07008747 if (!enabled)
8748 return omx->m_out_mem_ptr;
8749 return m_out_mem_ptr_client;
8750}
8751
8752 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
8753(OMX_BUFFERHEADERTYPE *bufadd)
8754{
8755 if (!omx) {
8756 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8757 return NULL;
8758 }
8759 if (!enabled)
8760 return bufadd;
8761
8762 unsigned index = 0;
8763 index = bufadd - omx->m_out_mem_ptr;
8764 if (index < omx->drv_ctx.op_buf.actualcount) {
8765 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
8766 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
8767 bool status;
8768 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
8769 pthread_mutex_lock(&omx->c_lock);
8770 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
8771 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
8772 pmem_baseaddress[index], pmem_baseaddress[index]);
8773 pthread_mutex_unlock(&omx->c_lock);
8774 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
8775 if (!status) {
8776 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
8777 m_out_mem_ptr_client[index].nFilledLen = 0;
8778 return &m_out_mem_ptr_client[index];
8779 }
8780 } else
8781 m_out_mem_ptr_client[index].nFilledLen = 0;
8782 return &m_out_mem_ptr_client[index];
8783 }
8784 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
8785 return NULL;
8786}
8787
8788 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
8789(OMX_BUFFERHEADERTYPE *bufadd)
8790{
8791 if (!omx) {
8792 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8793 return NULL;
8794 }
8795 if (!enabled)
8796 return bufadd;
8797 unsigned index = 0;
8798 index = bufadd - m_out_mem_ptr_client;
8799 if (index < omx->drv_ctx.op_buf.actualcount) {
8800 return &omx->m_out_mem_ptr[index];
8801 }
8802 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
8803 return NULL;
8804}
8805 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
8806(unsigned int &buffer_size)
8807{
8808 bool status = true;
8809 pthread_mutex_lock(&omx->c_lock);
8810 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008811 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07008812 else {
8813 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
8814 DEBUG_PRINT_ERROR("\n Get buffer size failed");
8815 status = false;
8816 goto fail_get_buffer_size;
8817 }
8818 }
8819 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
8820 buffer_size = omx->drv_ctx.op_buf.buffer_size;
8821 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8822 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008823fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07008824 pthread_mutex_unlock(&omx->c_lock);
8825 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008826}
8827OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07008828 OMX_BUFFERHEADERTYPE *bufhdr)
8829{
8830 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008831
Arun Menon906de572013-06-18 17:01:40 -07008832 if (!enabled)
8833 return omx->free_output_buffer(bufhdr);
8834 if (enabled && omx->is_component_secure())
8835 return OMX_ErrorNone;
8836 if (!allocated_count || !bufhdr) {
8837 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
8838 return OMX_ErrorBadParameter;
8839 }
8840 index = bufhdr - m_out_mem_ptr_client;
8841 if (index >= omx->drv_ctx.op_buf.actualcount) {
8842 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
8843 return OMX_ErrorBadParameter;
8844 }
8845 if (pmem_fd[index] > 0) {
8846 munmap(pmem_baseaddress[index], buffer_size_req);
8847 close(pmem_fd[index]);
8848 }
8849 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008850#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008851 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008852#endif
Arun Menon906de572013-06-18 17:01:40 -07008853 m_heap_ptr[index].video_heap_ptr = NULL;
8854 if (allocated_count > 0)
8855 allocated_count--;
8856 else
8857 allocated_count = 0;
8858 if (!allocated_count) {
8859 pthread_mutex_lock(&omx->c_lock);
8860 c2d.close();
8861 init_members();
8862 pthread_mutex_unlock(&omx->c_lock);
8863 }
8864 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008865}
8866
8867OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07008868 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008869{
Arun Menon906de572013-06-18 17:01:40 -07008870 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8871 if (!enabled) {
8872 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
8873 return eRet;
8874 }
8875 if (enabled && omx->is_component_secure()) {
8876 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
8877 omx->is_component_secure());
8878 return OMX_ErrorUnsupportedSetting;
8879 }
8880 if (!bufferHdr || bytes > buffer_size_req) {
8881 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
8882 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
8883 buffer_size_req,bytes);
8884 return OMX_ErrorBadParameter;
8885 }
8886 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
8887 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
8888 return OMX_ErrorInsufficientResources;
8889 }
8890 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
8891 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
8892 port,appData,omx->drv_ctx.op_buf.buffer_size);
8893 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
8894 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
8895 return eRet;
8896 }
8897 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
8898 omx->drv_ctx.op_buf.actualcount) {
8899 DEBUG_PRINT_ERROR("\n Invalid header index %d",
8900 (temp_bufferHdr - omx->m_out_mem_ptr));
8901 return OMX_ErrorUndefined;
8902 }
8903 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008904#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008905 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
8906 buffer_size_req,buffer_alignment_req,
8907 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
8908 0);
8909 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
8910 if (op_buf_ion_info[i].ion_device_fd < 0) {
8911 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
8912 return OMX_ErrorInsufficientResources;
8913 }
8914 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
8915 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008916
Arun Menon906de572013-06-18 17:01:40 -07008917 if (pmem_baseaddress[i] == MAP_FAILED) {
8918 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
8919 close(pmem_fd[i]);
8920 omx->free_ion_memory(&op_buf_ion_info[i]);
8921 return OMX_ErrorInsufficientResources;
8922 }
8923 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
8924 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
8925 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008926#endif
Arun Menon906de572013-06-18 17:01:40 -07008927 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
8928 m_pmem_info_client[i].offset = 0;
8929 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
8930 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8931 m_platform_list_client[i].nEntries = 1;
8932 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
8933 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
8934 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
8935 m_out_mem_ptr_client[i].nFilledLen = 0;
8936 m_out_mem_ptr_client[i].nFlags = 0;
8937 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8938 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
8939 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
8940 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
8941 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
8942 m_out_mem_ptr_client[i].pAppPrivate = appData;
8943 *bufferHdr = &m_out_mem_ptr_client[i];
8944 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
8945 allocated_count++;
8946 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008947}
8948
8949bool omx_vdec::is_component_secure()
8950{
Arun Menon906de572013-06-18 17:01:40 -07008951 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008952}
8953
8954bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
8955{
Arun Menon906de572013-06-18 17:01:40 -07008956 bool status = true;
8957 if (!enabled) {
8958 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8959 dest_color_format = (OMX_COLOR_FORMATTYPE)
8960 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8961 else
8962 status = false;
8963 } else {
8964 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8965 status = false;
8966 } else
8967 dest_color_format = OMX_COLOR_FormatYUV420Planar;
8968 }
8969 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008970}
Arun Menonbdb80b02013-08-12 17:45:54 -07008971
8972#ifdef META_DATA_MODE_SUPPORTED
8973void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
8974{
8975 int i = 0;
8976 bool buf_present = false;
8977 pthread_mutex_lock(&m_lock);
8978 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
8979 //check the buffer fd, offset, uv addr with list contents
8980 //If present increment reference.
8981 if ((out_dynamic_list[i].fd == fd) &&
8982 (out_dynamic_list[i].offset == offset)) {
8983 out_dynamic_list[i].ref_count++;
8984 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d\n",
8985 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
8986 buf_present = true;
8987 break;
8988 }
8989 }
8990 if (!buf_present) {
8991 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
8992 //search for a entry to insert details of the new buffer
8993 if (out_dynamic_list[i].dup_fd == 0) {
8994 out_dynamic_list[i].fd = fd;
8995 out_dynamic_list[i].offset = offset;
8996 out_dynamic_list[i].dup_fd = dup(fd);
8997 out_dynamic_list[i].ref_count++;
8998 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d\n",
8999 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9000 break;
9001 }
9002 }
9003 }
9004 pthread_mutex_unlock(&m_lock);
9005}
9006
9007void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
9008{
9009 int i = 0;
9010 pthread_mutex_lock(&m_lock);
9011 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
9012 //check the buffer fd, offset, uv addr with list contents
9013 //If present decrement reference.
9014 if ((out_dynamic_list[i].fd == fd) &&
9015 (out_dynamic_list[i].offset == offset)) {
9016 out_dynamic_list[i].ref_count--;
9017 if (out_dynamic_list[i].ref_count == 0) {
9018 close(out_dynamic_list[i].dup_fd);
9019 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d\n",
9020 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9021 out_dynamic_list[i].dup_fd = 0;
9022 out_dynamic_list[i].fd = 0;
9023 out_dynamic_list[i].offset = 0;
9024 }
9025 break;
9026 }
9027 }
9028 if (i >= drv_ctx.op_buf.actualcount) {
9029 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list\n");
9030 }
9031 pthread_mutex_unlock(&m_lock);
9032}
9033#endif