blob: 3794ce9463640aed8490aa6be36b4093b627e823 [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>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080052#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070053
54#ifndef _ANDROID_
55#include <sys/ioctl.h>
56#include <sys/mman.h>
57#endif //_ANDROID_
58
59#ifdef _ANDROID_
60#include <cutils/properties.h>
61#undef USE_EGL_IMAGE_GPU
62#endif
63
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070064#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070065
66#ifdef _ANDROID_
67#include "DivXDrmDecrypt.h"
68#endif //_ANDROID_
69
70#ifdef USE_EGL_IMAGE_GPU
71#include <EGL/egl.h>
72#include <EGL/eglQCOM.h>
73#define EGL_BUFFER_HANDLE_QCOM 0x4F00
74#define EGL_BUFFER_OFFSET_QCOM 0x4F01
75#endif
Vinay Kalia21649b32013-03-18 17:28:07 -070076
Jayasena Sangaraboina51230642013-08-21 18:02:13 -070077#define BUFFER_LOG_LOC "/data/misc/media"
78
Shalaj Jain273b3e02012-06-22 19:08:03 -070079#ifdef OUTPUT_EXTRADATA_LOG
80FILE *outputExtradataFile;
81char ouputextradatafilename [] = "/data/extradata";
82#endif
83
84#define DEFAULT_FPS 30
85#define MAX_INPUT_ERROR DEFAULT_FPS
86#define MAX_SUPPORTED_FPS 120
87
88#define VC1_SP_MP_START_CODE 0xC5000000
89#define VC1_SP_MP_START_CODE_MASK 0xFF000000
90#define VC1_AP_SEQ_START_CODE 0x0F010000
91#define VC1_STRUCT_C_PROFILE_MASK 0xF0
92#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
93#define VC1_SIMPLE_PROFILE 0
94#define VC1_MAIN_PROFILE 1
95#define VC1_ADVANCE_PROFILE 3
96#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
97#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
98#define VC1_STRUCT_C_LEN 4
99#define VC1_STRUCT_C_POS 8
100#define VC1_STRUCT_A_POS 12
101#define VC1_STRUCT_B_POS 24
102#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700103#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700104
105#define MEM_DEVICE "/dev/ion"
106#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
107
108#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700109extern "C" {
110#include<utils/Log.h>
111}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700112#endif//_ANDROID_
113
Vinay Kalia53fa6832012-10-11 17:55:30 -0700114#define SZ_4K 0x1000
115#define SZ_1M 0x100000
116
Shalaj Jain273b3e02012-06-22 19:08:03 -0700117#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
118#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 -0700119#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
120
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800121#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700122
123int debug_level = PRIO_ERROR;
124
Shalaj Jain273b3e02012-06-22 19:08:03 -0700125void* async_message_thread (void *input)
126{
Arun Menon906de572013-06-18 17:01:40 -0700127 OMX_BUFFERHEADERTYPE *buffer;
128 struct v4l2_plane plane[VIDEO_MAX_PLANES];
129 struct pollfd pfd;
130 struct v4l2_buffer v4l2_buf;
131 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
132 struct v4l2_event dqevent;
133 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
134 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
135 pfd.fd = omx->drv_ctx.video_driver_fd;
136 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
137 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
138 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
139 while (1) {
140 rc = poll(&pfd, 1, POLL_TIMEOUT);
141 if (!rc) {
142 DEBUG_PRINT_ERROR("Poll timedout\n");
143 break;
144 } else if (rc < 0) {
145 DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
146 break;
147 }
148 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
149 struct vdec_msginfo vdec_msg;
150 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
151 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
152 v4l2_buf.length = omx->drv_ctx.num_planes;
153 v4l2_buf.m.planes = plane;
154 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
155 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
156 vdec_msg.status_code=VDEC_S_SUCCESS;
157 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
158 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
159 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
160 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
161 (uint64_t)v4l2_buf.timestamp.tv_usec;
162 if (vdec_msg.msgdata.output_frame.len) {
163 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
164 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
165 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
166 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
167 }
168 if (omx->async_message_process(input,&vdec_msg) < 0) {
169 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
170 break;
171 }
172 }
173 }
174 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
175 struct vdec_msginfo vdec_msg;
176 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
177 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
178 v4l2_buf.length = 1;
179 v4l2_buf.m.planes = plane;
180 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
181 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
182 vdec_msg.status_code=VDEC_S_SUCCESS;
183 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
184 if (omx->async_message_process(input,&vdec_msg) < 0) {
185 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
186 break;
187 }
188 }
189 }
190 if (pfd.revents & POLLPRI) {
191 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
192 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
193 struct vdec_msginfo vdec_msg;
194 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
195 vdec_msg.status_code=VDEC_S_SUCCESS;
196 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved insufficient\n");
197 if (omx->async_message_process(input,&vdec_msg) < 0) {
198 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
199 break;
200 }
201 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
202 struct vdec_msginfo vdec_msg;
203 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
204 vdec_msg.status_code=VDEC_S_SUCCESS;
205 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved \n");
206 if (omx->async_message_process(input,&vdec_msg) < 0) {
207 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
208 break;
209 }
210 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
211 vdec_msg.status_code=VDEC_S_SUCCESS;
212 DEBUG_PRINT_HIGH("VIDC Output 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 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
218 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
219 break;
220 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
221 struct vdec_msginfo vdec_msg;
222 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
223 vdec_msg.status_code=VDEC_S_SUCCESS;
224 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
225 if (omx->async_message_process(input,&vdec_msg) < 0) {
226 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
227 break;
228 }
229 } else {
230 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
231 continue;
232 }
233 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700234 }
Arun Menon906de572013-06-18 17:01:40 -0700235 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
236 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700237}
238
239void* message_thread(void *input)
240{
Arun Menon906de572013-06-18 17:01:40 -0700241 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
242 unsigned char id;
243 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700244
Arun Menon906de572013-06-18 17:01:40 -0700245 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
246 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
247 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700248
Arun Menon906de572013-06-18 17:01:40 -0700249 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700250
Arun Menon906de572013-06-18 17:01:40 -0700251 if (0 == n) {
252 break;
253 }
254
255 if (1 == n) {
256 omx->process_event_cb(omx, id);
257 }
258 if ((n < 0) && (errno != EINTR)) {
259 DEBUG_PRINT_LOW("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
260 break;
261 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700262 }
Arun Menon906de572013-06-18 17:01:40 -0700263 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
264 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700265}
266
267void post_message(omx_vdec *omx, unsigned char id)
268{
Arun Menon906de572013-06-18 17:01:40 -0700269 int ret_value;
270 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
271 ret_value = write(omx->m_pipe_out, &id, 1);
272 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700273}
274
275// omx_cmd_queue destructor
276omx_vdec::omx_cmd_queue::~omx_cmd_queue()
277{
Arun Menon906de572013-06-18 17:01:40 -0700278 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700279}
280
281// omx cmd queue constructor
282omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
283{
284 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
285}
286
287// omx cmd queue insert
288bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
289{
Arun Menon906de572013-06-18 17:01:40 -0700290 bool ret = true;
291 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
292 m_q[m_write].id = id;
293 m_q[m_write].param1 = p1;
294 m_q[m_write].param2 = p2;
295 m_write++;
296 m_size ++;
297 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
298 m_write = 0;
299 }
300 } else {
301 ret = false;
302 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700303 }
Arun Menon906de572013-06-18 17:01:40 -0700304 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700305}
306
307// omx cmd queue pop
308bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
309{
Arun Menon906de572013-06-18 17:01:40 -0700310 bool ret = true;
311 if (m_size > 0) {
312 *id = m_q[m_read].id;
313 *p1 = m_q[m_read].param1;
314 *p2 = m_q[m_read].param2;
315 // Move the read pointer ahead
316 ++m_read;
317 --m_size;
318 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
319 m_read = 0;
320 }
321 } else {
322 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700323 }
Arun Menon906de572013-06-18 17:01:40 -0700324 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700325}
326
327// Retrieve the first mesg type in the queue
328unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
329{
330 return m_q[m_read].id;
331}
332
333#ifdef _ANDROID_
334omx_vdec::ts_arr_list::ts_arr_list()
335{
Arun Menon906de572013-06-18 17:01:40 -0700336 //initialize timestamps array
337 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700338}
339omx_vdec::ts_arr_list::~ts_arr_list()
340{
Arun Menon906de572013-06-18 17:01:40 -0700341 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700342}
343
344bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
345{
Arun Menon906de572013-06-18 17:01:40 -0700346 bool ret = true;
347 bool duplicate_ts = false;
348 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700349
Arun Menon906de572013-06-18 17:01:40 -0700350 //insert at the first available empty location
351 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
352 if (!m_ts_arr_list[idx].valid) {
353 //found invalid or empty entry, save timestamp
354 m_ts_arr_list[idx].valid = true;
355 m_ts_arr_list[idx].timestamp = ts;
356 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
357 ts, idx);
358 break;
359 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700360 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700361
Arun Menon906de572013-06-18 17:01:40 -0700362 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
363 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
364 ret = false;
365 }
366 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700367}
368
369bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
370{
Arun Menon906de572013-06-18 17:01:40 -0700371 bool ret = true;
372 int min_idx = -1;
373 OMX_TICKS min_ts = 0;
374 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700375
Arun Menon906de572013-06-18 17:01:40 -0700376 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700377
Arun Menon906de572013-06-18 17:01:40 -0700378 if (m_ts_arr_list[idx].valid) {
379 //found valid entry, save index
380 if (min_idx < 0) {
381 //first valid entry
382 min_ts = m_ts_arr_list[idx].timestamp;
383 min_idx = idx;
384 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
385 min_ts = m_ts_arr_list[idx].timestamp;
386 min_idx = idx;
387 }
388 }
389
Shalaj Jain273b3e02012-06-22 19:08:03 -0700390 }
391
Arun Menon906de572013-06-18 17:01:40 -0700392 if (min_idx < 0) {
393 //no valid entries found
394 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
395 ts = 0;
396 ret = false;
397 } else {
398 ts = m_ts_arr_list[min_idx].timestamp;
399 m_ts_arr_list[min_idx].valid = false;
400 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
401 ts, min_idx);
402 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700403
Arun Menon906de572013-06-18 17:01:40 -0700404 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700405
406}
407
408
409bool omx_vdec::ts_arr_list::reset_ts_list()
410{
Arun Menon906de572013-06-18 17:01:40 -0700411 bool ret = true;
412 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700413
Arun Menon906de572013-06-18 17:01:40 -0700414 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
415 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
416 m_ts_arr_list[idx].valid = false;
417 }
418 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700419}
420#endif
421
422// factory function executed by the core to create instances
423void *get_omx_component_factory_fn(void)
424{
Arun Menon906de572013-06-18 17:01:40 -0700425 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700426}
427
428#ifdef _ANDROID_
429#ifdef USE_ION
430VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700431 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700432{
Arun Menon906de572013-06-18 17:01:40 -0700433 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700434}
435#else
436VideoHeap::VideoHeap(int fd, size_t size, void* base)
437{
438 // dup file descriptor, map once, use pmem
439 init(dup(fd), base, size, 0 , MEM_DEVICE);
440}
441#endif
442#endif // _ANDROID_
443/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700444 FUNCTION
445 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700446
Arun Menon906de572013-06-18 17:01:40 -0700447 DESCRIPTION
448 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700449
Arun Menon906de572013-06-18 17:01:40 -0700450 PARAMETERS
451 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700452
Arun Menon906de572013-06-18 17:01:40 -0700453 RETURN VALUE
454 None.
455 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800456omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700457 m_state(OMX_StateInvalid),
458 m_app_data(NULL),
459 m_inp_mem_ptr(NULL),
460 m_out_mem_ptr(NULL),
461 m_inp_err_count(0),
462 input_flush_progress (false),
463 output_flush_progress (false),
464 input_use_buffer (false),
465 output_use_buffer (false),
466 ouput_egl_buffers(false),
467 m_use_output_pmem(OMX_FALSE),
468 m_out_mem_region_smi(OMX_FALSE),
469 m_out_pvt_entry_pmem(OMX_FALSE),
470 pending_input_buffers(0),
471 pending_output_buffers(0),
472 m_out_bm_count(0),
473 m_inp_bm_count(0),
474 m_inp_bPopulated(OMX_FALSE),
475 m_out_bPopulated(OMX_FALSE),
476 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700477#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700478 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700479#endif
Arun Menon906de572013-06-18 17:01:40 -0700480 m_inp_bEnabled(OMX_TRUE),
481 m_out_bEnabled(OMX_TRUE),
482 m_in_alloc_cnt(0),
483 m_platform_list(NULL),
484 m_platform_entry(NULL),
485 m_pmem_info(NULL),
486 arbitrary_bytes (true),
487 psource_frame (NULL),
488 pdest_frame (NULL),
489 m_inp_heap_ptr (NULL),
490 m_phdr_pmem_ptr(NULL),
491 m_heap_inp_bm_count (0),
492 codec_type_parse ((codec_type)0),
493 first_frame_meta (true),
494 frame_count (0),
495 nal_count (0),
496 nal_length(0),
497 look_ahead_nal (false),
498 first_frame(0),
499 first_buffer(NULL),
500 first_frame_size (0),
501 m_device_file_ptr(NULL),
502 m_vc1_profile((vc1_profile_type)0),
503 m_profile(0),
504 h264_last_au_ts(LLONG_MAX),
505 h264_last_au_flags(0),
506 prev_ts(LLONG_MAX),
507 rst_prev_ts(true),
508 frm_int(0),
509 m_disp_hor_size(0),
510 m_disp_vert_size(0),
511 in_reconfig(false),
512 m_display_id(NULL),
513 h264_parser(NULL),
514 client_extradata(0),
515 m_reject_avc_1080p_mp (0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700516#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700517 m_enable_android_native_buffers(OMX_FALSE),
518 m_use_android_native_buffers(OMX_FALSE),
519 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700520#endif
Arun Menon906de572013-06-18 17:01:40 -0700521 m_desc_buffer_ptr(NULL),
522 secure_mode(false),
523 client_set_fps(false)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700524{
Arun Menon906de572013-06-18 17:01:40 -0700525 /* Assumption is that , to begin with , we have all the frames with decoder */
526 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700527 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700528#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700529 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700530 property_get("vidc.debug.level", property_value, "0");
531 debug_level = atoi(property_value);
532 property_value[0] = '\0';
533
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700534 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
535
Arun Menon906de572013-06-18 17:01:40 -0700536 property_get("vidc.dec.debug.perf", property_value, "0");
537 perf_flag = atoi(property_value);
538 if (perf_flag) {
539 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
540 dec_time.start();
541 proc_frms = latency = 0;
542 }
543 prev_n_filled_len = 0;
544 property_value[0] = '\0';
545 property_get("vidc.dec.debug.ts", property_value, "0");
546 m_debug_timestamp = atoi(property_value);
547 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
548 if (m_debug_timestamp) {
549 time_stamp_dts.set_timestamp_reorder_mode(true);
550 time_stamp_dts.enable_debug_print(true);
551 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700552
Arun Menon906de572013-06-18 17:01:40 -0700553 property_value[0] = '\0';
554 property_get("vidc.dec.debug.concealedmb", property_value, "0");
555 m_debug_concealedmb = atoi(property_value);
556 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700557
Arun Menon906de572013-06-18 17:01:40 -0700558 property_value[0] = '\0';
559 property_get("vidc.dec.profile.check", property_value, "0");
560 m_reject_avc_1080p_mp = atoi(property_value);
561 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530562
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700563 property_value[0] = '\0';
564 property_get("vidc.dec.log.in", property_value, "0");
565 m_debug.in_buffer_log = atoi(property_value);
566
567 property_value[0] = '\0';
568 property_get("vidc.dec.log.out", property_value, "0");
569 m_debug.out_buffer_log = atoi(property_value);
570 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
571
572 property_value[0] = '\0';
573 property_get("vidc.log.loc", property_value, "");
574 if (*property_value)
575 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700576#endif
Arun Menon906de572013-06-18 17:01:40 -0700577 memset(&m_cmp,0,sizeof(m_cmp));
578 memset(&m_cb,0,sizeof(m_cb));
579 memset (&drv_ctx,0,sizeof(drv_ctx));
580 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
581 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
582 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
583 m_demux_entries = 0;
584 msg_thread_id = 0;
585 async_thread_id = 0;
586 msg_thread_created = false;
587 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700588#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700589 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700590#endif
Arun Menon906de572013-06-18 17:01:40 -0700591 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
592 drv_ctx.timestamp_adjust = false;
593 drv_ctx.video_driver_fd = -1;
594 m_vendor_config.pData = NULL;
595 pthread_mutex_init(&m_lock, NULL);
596 pthread_mutex_init(&c_lock, NULL);
597 sem_init(&m_cmd_lock,0,0);
598 streaming[CAPTURE_PORT] =
599 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700600#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700601 char extradata_value[PROPERTY_VALUE_MAX] = {0};
602 property_get("vidc.dec.debug.extradata", extradata_value, "0");
603 m_debug_extradata = atoi(extradata_value);
604 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700605#endif
Arun Menon906de572013-06-18 17:01:40 -0700606 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
607 client_buffers.set_vdec_client(this);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700608}
609
Vinay Kalia85793762012-06-14 19:12:34 -0700610static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700611 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
612 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
613 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
614 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
615 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700616};
617
618static OMX_ERRORTYPE subscribe_to_events(int fd)
619{
Arun Menon906de572013-06-18 17:01:40 -0700620 OMX_ERRORTYPE eRet = OMX_ErrorNone;
621 struct v4l2_event_subscription sub;
622 int array_sz = sizeof(event_type)/sizeof(int);
623 int i,rc;
624 if (fd < 0) {
625 printf("Invalid input: %d\n", fd);
626 return OMX_ErrorBadParameter;
627 }
Vinay Kalia85793762012-06-14 19:12:34 -0700628
Arun Menon906de572013-06-18 17:01:40 -0700629 for (i = 0; i < array_sz; ++i) {
630 memset(&sub, 0, sizeof(sub));
631 sub.type = event_type[i];
632 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
633 if (rc) {
634 printf("Failed to subscribe event: 0x%x\n", sub.type);
635 break;
636 }
637 }
638 if (i < array_sz) {
639 for (--i; i >=0 ; i--) {
640 memset(&sub, 0, sizeof(sub));
641 sub.type = event_type[i];
642 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
643 if (rc)
644 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
645 }
646 eRet = OMX_ErrorNotImplemented;
647 }
648 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700649}
650
651
652static OMX_ERRORTYPE unsubscribe_to_events(int fd)
653{
Arun Menon906de572013-06-18 17:01:40 -0700654 OMX_ERRORTYPE eRet = OMX_ErrorNone;
655 struct v4l2_event_subscription sub;
656 int array_sz = sizeof(event_type)/sizeof(int);
657 int i,rc;
658 if (fd < 0) {
659 printf("Invalid input: %d\n", fd);
660 return OMX_ErrorBadParameter;
661 }
Vinay Kalia85793762012-06-14 19:12:34 -0700662
Arun Menon906de572013-06-18 17:01:40 -0700663 for (i = 0; i < array_sz; ++i) {
664 memset(&sub, 0, sizeof(sub));
665 sub.type = event_type[i];
666 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
667 if (rc) {
668 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
669 break;
670 }
671 }
672 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700673}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700674
675/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700676 FUNCTION
677 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700678
Arun Menon906de572013-06-18 17:01:40 -0700679 DESCRIPTION
680 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700681
Arun Menon906de572013-06-18 17:01:40 -0700682 PARAMETERS
683 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700684
Arun Menon906de572013-06-18 17:01:40 -0700685 RETURN VALUE
686 None.
687 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700688omx_vdec::~omx_vdec()
689{
Arun Menon906de572013-06-18 17:01:40 -0700690 m_pmem_info = NULL;
691 struct v4l2_decoder_cmd dec;
692 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
693 if (m_pipe_in) close(m_pipe_in);
694 if (m_pipe_out) close(m_pipe_out);
695 m_pipe_in = -1;
696 m_pipe_out = -1;
697 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
698 if (msg_thread_created)
699 pthread_join(msg_thread_id,NULL);
700 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
701 dec.cmd = V4L2_DEC_CMD_STOP;
702 if (drv_ctx.video_driver_fd >=0 ) {
703 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
704 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
705 }
706 if (async_thread_created)
707 pthread_join(async_thread_id,NULL);
708 unsubscribe_to_events(drv_ctx.video_driver_fd);
709 close(drv_ctx.video_driver_fd);
710 pthread_mutex_destroy(&m_lock);
711 pthread_mutex_destroy(&c_lock);
712 sem_destroy(&m_cmd_lock);
713 if (perf_flag) {
714 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
715 dec_time.end();
716 }
717 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700718}
719
Arun Menon906de572013-06-18 17:01:40 -0700720int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
721{
722 struct v4l2_requestbuffers bufreq;
723 int rc = 0;
724 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
725 bufreq.memory = V4L2_MEMORY_USERPTR;
726 bufreq.count = 0;
727 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
728 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530729 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
730 bufreq.memory = V4L2_MEMORY_USERPTR;
731 bufreq.count = 0;
732 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
733 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700734 }
735 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700736}
737
Shalaj Jain273b3e02012-06-22 19:08:03 -0700738/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700739 FUNCTION
740 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700741
Arun Menon906de572013-06-18 17:01:40 -0700742 DESCRIPTION
743 IL Client callbacks are generated through this routine. The decoder
744 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700745
Arun Menon906de572013-06-18 17:01:40 -0700746 PARAMETERS
747 ctxt -- Context information related to the self.
748 id -- Event identifier. This could be any of the following:
749 1. Command completion event
750 2. Buffer done callback event
751 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700752
Arun Menon906de572013-06-18 17:01:40 -0700753 RETURN VALUE
754 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700755
Arun Menon906de572013-06-18 17:01:40 -0700756 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700757void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
758{
Arun Menon906de572013-06-18 17:01:40 -0700759 signed p1; // Parameter - 1
760 signed p2; // Parameter - 2
761 unsigned ident;
762 unsigned qsize=0; // qsize
763 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700764
Arun Menon906de572013-06-18 17:01:40 -0700765 if (!pThis) {
766 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
767 __func__);
768 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700769 }
770
Arun Menon906de572013-06-18 17:01:40 -0700771 // Protect the shared queue data structure
772 do {
773 /*Read the message id's from the queue*/
774 pthread_mutex_lock(&pThis->m_lock);
775 qsize = pThis->m_cmd_q.m_size;
776 if (qsize) {
777 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700778 }
Arun Menon906de572013-06-18 17:01:40 -0700779
780 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
781 qsize = pThis->m_ftb_q.m_size;
782 if (qsize) {
783 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
784 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700785 }
Arun Menon906de572013-06-18 17:01:40 -0700786
787 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
788 qsize = pThis->m_etb_q.m_size;
789 if (qsize) {
790 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
791 }
792 }
793 pthread_mutex_unlock(&pThis->m_lock);
794
795 /*process message if we have one*/
796 if (qsize > 0) {
797 id = ident;
798 switch (id) {
799 case OMX_COMPONENT_GENERATE_EVENT:
800 if (pThis->m_cb.EventHandler) {
801 switch (p1) {
802 case OMX_CommandStateSet:
803 pThis->m_state = (OMX_STATETYPE) p2;
804 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
805 pThis->m_state);
806 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
807 OMX_EventCmdComplete, p1, p2, NULL);
808 break;
809
810 case OMX_EventError:
811 if (p2 == OMX_StateInvalid) {
812 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
813 pThis->m_state = (OMX_STATETYPE) p2;
814 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
815 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
816 } else if (p2 == OMX_ErrorHardware) {
817 pThis->omx_report_error();
818 } else {
819 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
820 OMX_EventError, p2, (OMX_U32)NULL, NULL );
821 }
822 break;
823
824 case OMX_CommandPortDisable:
825 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
826 if (BITMASK_PRESENT(&pThis->m_flags,
827 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
828 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
829 break;
830 }
831 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
832 OMX_ERRORTYPE eRet = OMX_ErrorNone;
833 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
834 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
835 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
836 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
837 pThis->in_reconfig = false;
838 if (eRet != OMX_ErrorNone) {
839 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
840 pThis->omx_report_error();
841 break;
842 }
843 }
844 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
845 OMX_EventCmdComplete, p1, p2, NULL );
846 break;
847 case OMX_CommandPortEnable:
848 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
849 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
850 OMX_EventCmdComplete, p1, p2, NULL );
851 break;
852
853 default:
854 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
855 OMX_EventCmdComplete, p1, p2, NULL );
856 break;
857
858 }
859 } else {
860 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
861 }
862 break;
863 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
864 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
865 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
866 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
867 pThis->omx_report_error ();
868 }
869 break;
870 case OMX_COMPONENT_GENERATE_ETB:
871 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
872 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
873 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
874 pThis->omx_report_error ();
875 }
876 break;
877
878 case OMX_COMPONENT_GENERATE_FTB:
879 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
880 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
881 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
882 pThis->omx_report_error ();
883 }
884 break;
885
886 case OMX_COMPONENT_GENERATE_COMMAND:
887 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
888 (OMX_U32)p2,(OMX_PTR)NULL);
889 break;
890
891 case OMX_COMPONENT_GENERATE_EBD:
892
893 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
894 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
895 pThis->omx_report_error ();
896 } else {
897 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
898 pThis->m_inp_err_count++;
899 pThis->time_stamp_dts.remove_time_stamp(
900 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
901 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
902 ?true:false);
903 } else {
904 pThis->m_inp_err_count = 0;
905 }
906 if ( pThis->empty_buffer_done(&pThis->m_cmp,
907 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
908 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
909 pThis->omx_report_error ();
910 }
911 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
912 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
913 pThis->omx_report_error ();
914 }
915 }
916 break;
917 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
918 int64_t *timestamp = (int64_t *)p1;
919 if (p1) {
920 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
921 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
922 ?true:false);
923 free(timestamp);
924 }
925 }
926 break;
927 case OMX_COMPONENT_GENERATE_FBD:
928 if (p2 != VDEC_S_SUCCESS) {
929 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
930 pThis->omx_report_error ();
931 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
932 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
933 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
934 pThis->omx_report_error ();
935 }
936 break;
937
938 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
939 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
940 if (!pThis->input_flush_progress) {
941 DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
942 } else {
943 pThis->execute_input_flush();
944 if (pThis->m_cb.EventHandler) {
945 if (p2 != VDEC_S_SUCCESS) {
946 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
947 pThis->omx_report_error ();
948 } else {
949 /*Check if we need generate event for Flush done*/
950 if (BITMASK_PRESENT(&pThis->m_flags,
951 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
952 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
953 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
954 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
955 OMX_EventCmdComplete,OMX_CommandFlush,
956 OMX_CORE_INPUT_PORT_INDEX,NULL );
957 }
958 if (BITMASK_PRESENT(&pThis->m_flags,
959 OMX_COMPONENT_IDLE_PENDING)) {
960 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
961 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
962 pThis->omx_report_error ();
963 } else {
964 pThis->streaming[OUTPUT_PORT] = false;
965 }
966 if (!pThis->output_flush_progress) {
967 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
968 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
969 OMX_COMPONENT_GENERATE_STOP_DONE);
970 }
971 }
972 }
973 } else {
974 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
975 }
976 }
977 break;
978
979 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
980 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
981 if (!pThis->output_flush_progress) {
982 DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
983 } else {
984 pThis->execute_output_flush();
985 if (pThis->m_cb.EventHandler) {
986 if (p2 != VDEC_S_SUCCESS) {
987 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
988 pThis->omx_report_error ();
989 } else {
990 /*Check if we need generate event for Flush done*/
991 if (BITMASK_PRESENT(&pThis->m_flags,
992 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
993 DEBUG_PRINT_LOW("\n Notify Output Flush done");
994 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
995 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
996 OMX_EventCmdComplete,OMX_CommandFlush,
997 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
998 }
999 if (BITMASK_PRESENT(&pThis->m_flags,
1000 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
1001 DEBUG_PRINT_LOW("\n Internal flush complete");
1002 BITMASK_CLEAR (&pThis->m_flags,
1003 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1004 if (BITMASK_PRESENT(&pThis->m_flags,
1005 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1006 pThis->post_event(OMX_CommandPortDisable,
1007 OMX_CORE_OUTPUT_PORT_INDEX,
1008 OMX_COMPONENT_GENERATE_EVENT);
1009 BITMASK_CLEAR (&pThis->m_flags,
1010 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1011
1012 }
1013 }
1014
1015 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1016 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
1017 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1018 pThis->omx_report_error ();
1019 break;
1020 }
1021 pThis->streaming[CAPTURE_PORT] = false;
1022 if (!pThis->input_flush_progress) {
1023 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
1024 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1025 OMX_COMPONENT_GENERATE_STOP_DONE);
1026 }
1027 }
1028 }
1029 } else {
1030 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1031 }
1032 }
1033 break;
1034
1035 case OMX_COMPONENT_GENERATE_START_DONE:
1036 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1037
1038 if (pThis->m_cb.EventHandler) {
1039 if (p2 != VDEC_S_SUCCESS) {
1040 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1041 pThis->omx_report_error ();
1042 } else {
1043 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1044 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1045 DEBUG_PRINT_LOW("\n Move to executing");
1046 // Send the callback now
1047 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1048 pThis->m_state = OMX_StateExecuting;
1049 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1050 OMX_EventCmdComplete,OMX_CommandStateSet,
1051 OMX_StateExecuting, NULL);
1052 } else if (BITMASK_PRESENT(&pThis->m_flags,
1053 OMX_COMPONENT_PAUSE_PENDING)) {
1054 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1055 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
1056 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1057 pThis->omx_report_error ();
1058 }
1059 }
1060 }
1061 } else {
1062 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1063 }
1064 break;
1065
1066 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1067 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1068 if (pThis->m_cb.EventHandler) {
1069 if (p2 != VDEC_S_SUCCESS) {
1070 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1071 pThis->omx_report_error ();
1072 } else {
1073 pThis->complete_pending_buffer_done_cbs();
1074 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
1075 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1076 //Send the callback now
1077 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1078 pThis->m_state = OMX_StatePause;
1079 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1080 OMX_EventCmdComplete,OMX_CommandStateSet,
1081 OMX_StatePause, NULL);
1082 }
1083 }
1084 } else {
1085 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1086 }
1087
1088 break;
1089
1090 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1091 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1092 if (pThis->m_cb.EventHandler) {
1093 if (p2 != VDEC_S_SUCCESS) {
1094 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1095 pThis->omx_report_error ();
1096 } else {
1097 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1098 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1099 // Send the callback now
1100 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1101 pThis->m_state = OMX_StateExecuting;
1102 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1103 OMX_EventCmdComplete,OMX_CommandStateSet,
1104 OMX_StateExecuting,NULL);
1105 }
1106 }
1107 } else {
1108 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1109 }
1110
1111 break;
1112
1113 case OMX_COMPONENT_GENERATE_STOP_DONE:
1114 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1115 if (pThis->m_cb.EventHandler) {
1116 if (p2 != VDEC_S_SUCCESS) {
1117 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_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_IDLE_PENDING)) {
1122 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1123 // Send the callback now
1124 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1125 pThis->m_state = OMX_StateIdle;
1126 DEBUG_PRINT_LOW("\n Move to Idle State");
1127 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1128 OMX_EventCmdComplete,OMX_CommandStateSet,
1129 OMX_StateIdle,NULL);
1130 }
1131 }
1132 } else {
1133 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1134 }
1135
1136 break;
1137
1138 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1139 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
1140
1141 if (p2 == OMX_IndexParamPortDefinition) {
1142 pThis->in_reconfig = true;
1143 }
1144 if (pThis->m_cb.EventHandler) {
1145 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1146 OMX_EventPortSettingsChanged, p1, p2, NULL );
1147 } else {
1148 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1149 }
1150
Arun Menon906de572013-06-18 17:01:40 -07001151 break;
1152
1153 case OMX_COMPONENT_GENERATE_EOS_DONE:
1154 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1155 if (pThis->m_cb.EventHandler) {
1156 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1157 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1158 } else {
1159 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1160 }
1161 pThis->prev_ts = LLONG_MAX;
1162 pThis->rst_prev_ts = true;
1163 break;
1164
1165 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1166 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1167 pThis->omx_report_error ();
1168 break;
1169
1170 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1171 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
1172 pThis->omx_report_unsupported_setting();
1173 break;
1174
Arun Menon906de572013-06-18 17:01:40 -07001175 default:
1176 break;
1177 }
1178 }
1179 pthread_mutex_lock(&pThis->m_lock);
1180 qsize = pThis->m_cmd_q.m_size;
1181 if (pThis->m_state != OMX_StatePause)
1182 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1183 pthread_mutex_unlock(&pThis->m_lock);
1184 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001185
1186}
1187
Vinay Kaliab9e98102013-04-02 19:31:43 -07001188int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001189{
Arun Menon906de572013-06-18 17:01:40 -07001190 int format_changed = 0;
1191 if ((height != drv_ctx.video_resolution.frame_height) ||
1192 (width != drv_ctx.video_resolution.frame_width)) {
1193 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)\n",
1194 width, drv_ctx.video_resolution.frame_width,
1195 height,drv_ctx.video_resolution.frame_height);
1196 format_changed = 1;
1197 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001198 drv_ctx.video_resolution.frame_height = height;
1199 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001200 drv_ctx.video_resolution.scan_lines = scan_lines;
1201 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001202 rectangle.nLeft = 0;
1203 rectangle.nTop = 0;
1204 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1205 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Arun Menon906de572013-06-18 17:01:40 -07001206 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001207}
1208
Arun Menon6836ba02013-02-19 20:37:40 -08001209OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1210{
Arun Menon906de572013-06-18 17:01:40 -07001211 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1212 OMX_MAX_STRINGNAME_SIZE) &&
1213 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1214 m_decoder_capability.max_width = 1280;
1215 m_decoder_capability.max_height = 720;
1216 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1217 }
Arun Menon888aa852013-05-30 11:24:42 -07001218
Arun Menon906de572013-06-18 17:01:40 -07001219 if ((drv_ctx.video_resolution.frame_width *
1220 drv_ctx.video_resolution.frame_height >
1221 m_decoder_capability.max_width *
1222 m_decoder_capability.max_height) ||
1223 (drv_ctx.video_resolution.frame_width*
1224 drv_ctx.video_resolution.frame_height <
1225 m_decoder_capability.min_width *
1226 m_decoder_capability.min_height)) {
1227 DEBUG_PRINT_ERROR(
1228 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1229 drv_ctx.video_resolution.frame_width,
1230 drv_ctx.video_resolution.frame_height,
1231 m_decoder_capability.min_width,
1232 m_decoder_capability.min_height,
1233 m_decoder_capability.max_width,
1234 m_decoder_capability.max_height);
1235 return OMX_ErrorUnsupportedSetting;
1236 }
1237 DEBUG_PRINT_HIGH("\n video session supported\n");
1238 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001239}
1240
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001241int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1242{
1243 if (m_debug.in_buffer_log && !m_debug.infile) {
1244 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1245 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1246 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1247 }
1248 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1249 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); }
1250 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1251 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
1252 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1253 }
1254 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
1255 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1256 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1257 }
1258 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1259 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1260 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1261 }
1262 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1263 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1264 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1265 }
1266 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1267 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1268 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1269 }
1270 m_debug.infile = fopen (m_debug.infile_name, "ab");
1271 if (!m_debug.infile) {
1272 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging\n", m_debug.infile_name);
1273 m_debug.infile_name[0] = '\0';
1274 return -1;
1275 }
1276 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1277 struct ivf_file_header {
1278 OMX_U8 signature[4]; //='DKIF';
1279 OMX_U8 version ; //= 0;
1280 OMX_U8 headersize ; //= 32;
1281 OMX_U32 FourCC;
1282 OMX_U8 width;
1283 OMX_U8 height;
1284 OMX_U32 rate;
1285 OMX_U32 scale;
1286 OMX_U32 length;
1287 OMX_U8 unused[4];
1288 } file_header;
1289
1290 memset((void *)&file_header,0,sizeof(file_header));
1291 file_header.signature[0] = 'D';
1292 file_header.signature[1] = 'K';
1293 file_header.signature[2] = 'I';
1294 file_header.signature[3] = 'F';
1295 file_header.version = 0;
1296 file_header.headersize = 32;
1297 file_header.FourCC = 0x30385056;
1298 fwrite((const char *)&file_header,
1299 sizeof(file_header),1,m_debug.infile);
1300 }
1301 }
1302 if (m_debug.infile && buffer_addr && buffer_len) {
1303 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1304 struct vp8_ivf_frame_header {
1305 OMX_U32 framesize;
1306 OMX_U32 timestamp_lo;
1307 OMX_U32 timestamp_hi;
1308 } vp8_frame_header;
1309 vp8_frame_header.framesize = buffer_len;
1310 /* Currently FW doesn't use timestamp values */
1311 vp8_frame_header.timestamp_lo = 0;
1312 vp8_frame_header.timestamp_hi = 0;
1313 fwrite((const char *)&vp8_frame_header,
1314 sizeof(vp8_frame_header),1,m_debug.infile);
1315 }
1316 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1317 }
1318 return 0;
1319}
1320
1321int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1322 if (m_debug.out_buffer_log && !m_debug.outfile) {
1323 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1324 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1325 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1326 if (!m_debug.outfile) {
1327 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging\n", m_debug.outfile);
1328 m_debug.outfile_name[0] = '\0';
1329 return -1;
1330 }
1331 }
1332 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1333 int buf_index = buffer - m_out_mem_ptr;
1334 int stride = drv_ctx.video_resolution.stride;
1335 int scanlines = drv_ctx.video_resolution.scan_lines;
1336 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1337 unsigned i;
1338 int bytes_written = 0;
1339 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1340 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1341 temp += stride;
1342 }
1343 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1344 int stride_c = stride;
1345 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1346 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1347 temp += stride_c;
1348 }
1349 }
1350 return 0;
1351}
1352
Shalaj Jain273b3e02012-06-22 19:08:03 -07001353/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001354 FUNCTION
1355 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001356
Arun Menon906de572013-06-18 17:01:40 -07001357 DESCRIPTION
1358 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001359
Arun Menon906de572013-06-18 17:01:40 -07001360 PARAMETERS
1361 ctxt -- Context information related to the self.
1362 id -- Event identifier. This could be any of the following:
1363 1. Command completion event
1364 2. Buffer done callback event
1365 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001366
Arun Menon906de572013-06-18 17:01:40 -07001367 RETURN VALUE
1368 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001369
Arun Menon906de572013-06-18 17:01:40 -07001370 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001371OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1372{
1373
Arun Menon906de572013-06-18 17:01:40 -07001374 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1375 struct v4l2_fmtdesc fdesc;
1376 struct v4l2_format fmt;
1377 struct v4l2_requestbuffers bufreq;
1378 struct v4l2_control control;
1379 struct v4l2_frmsizeenum frmsize;
1380 unsigned int alignment = 0,buffer_size = 0;
1381 int fds[2];
1382 int r,ret=0;
1383 bool codec_ambiguous = false;
1384 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Sachin Shahc82a18f2013-03-29 14:45:38 -07001385
1386#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001387 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001388 property_get("ro.board.platform", platform_name, "0");
1389 if (!strncmp(platform_name, "msm8610", 7)) {
1390 device_name = (OMX_STRING)"/dev/video/q6_dec";
1391 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001392#endif
1393
Arun Menon906de572013-06-18 17:01:40 -07001394 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1395 struct v4l2_control control;
1396 secure_mode = true;
1397 arbitrary_bytes = false;
1398 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
1399 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001400
Arun Menon906de572013-06-18 17:01:40 -07001401 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001402
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001403 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d",
1404 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001405
Arun Menon906de572013-06-18 17:01:40 -07001406 if (drv_ctx.video_driver_fd == 0) {
1407 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again\n");
1408 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1409 close(0);
1410 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001411
Arun Menon906de572013-06-18 17:01:40 -07001412 if (drv_ctx.video_driver_fd < 0) {
1413 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1414 return OMX_ErrorInsufficientResources;
1415 }
1416 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1417 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001418
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001419 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001420 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001421 async_thread_created = true;
1422 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1423 }
1424 if (ret) {
1425 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1426 async_thread_created = false;
1427 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001428 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001429
Shalaj Jain273b3e02012-06-22 19:08:03 -07001430#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07001431 outputExtradataFile = fopen (ouputextradatafilename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001432#endif
1433
Arun Menon906de572013-06-18 17:01:40 -07001434 // Copy the role information which provides the decoder kind
1435 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001436
Arun Menon906de572013-06-18 17:01:40 -07001437 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1438 OMX_MAX_STRINGNAME_SIZE)) {
1439 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1440 OMX_MAX_STRINGNAME_SIZE);
1441 drv_ctx.timestamp_adjust = true;
1442 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1443 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1444 output_capability=V4L2_PIX_FMT_MPEG4;
1445 /*Initialize Start Code for MPEG4*/
1446 codec_type_parse = CODEC_TYPE_MPEG4;
1447 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001448 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1449 OMX_MAX_STRINGNAME_SIZE)) {
1450 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1451 OMX_MAX_STRINGNAME_SIZE);
1452 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1453 output_capability = V4L2_PIX_FMT_MPEG2;
1454 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1455 /*Initialize Start Code for MPEG2*/
1456 codec_type_parse = CODEC_TYPE_MPEG2;
1457 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001458 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1459 OMX_MAX_STRINGNAME_SIZE)) {
1460 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1461 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1462 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1463 eCompressionFormat = OMX_VIDEO_CodingH263;
1464 output_capability = V4L2_PIX_FMT_H263;
1465 codec_type_parse = CODEC_TYPE_H263;
1466 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001467 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1468 OMX_MAX_STRINGNAME_SIZE)) {
1469 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1470 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1471 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1472 output_capability = V4L2_PIX_FMT_DIVX_311;
1473 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1474 codec_type_parse = CODEC_TYPE_DIVX;
1475 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001476
Arun Menon906de572013-06-18 17:01:40 -07001477 eRet = createDivxDrmContext();
1478 if (eRet != OMX_ErrorNone) {
1479 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1480 return eRet;
1481 }
1482 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1483 OMX_MAX_STRINGNAME_SIZE)) {
1484 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1485 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1486 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1487 output_capability = V4L2_PIX_FMT_DIVX;
1488 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1489 codec_type_parse = CODEC_TYPE_DIVX;
1490 codec_ambiguous = true;
1491 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001492
Arun Menon906de572013-06-18 17:01:40 -07001493 eRet = createDivxDrmContext();
1494 if (eRet != OMX_ErrorNone) {
1495 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1496 return eRet;
1497 }
1498 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1499 OMX_MAX_STRINGNAME_SIZE)) {
1500 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1501 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1502 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1503 output_capability = V4L2_PIX_FMT_DIVX;
1504 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1505 codec_type_parse = CODEC_TYPE_DIVX;
1506 codec_ambiguous = true;
1507 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001508
Arun Menon906de572013-06-18 17:01:40 -07001509 eRet = createDivxDrmContext();
1510 if (eRet != OMX_ErrorNone) {
1511 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1512 return eRet;
1513 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001514
Arun Menon906de572013-06-18 17:01:40 -07001515 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1516 OMX_MAX_STRINGNAME_SIZE)) {
1517 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1518 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1519 output_capability=V4L2_PIX_FMT_H264;
1520 eCompressionFormat = OMX_VIDEO_CodingAVC;
1521 codec_type_parse = CODEC_TYPE_H264;
1522 m_frame_parser.init_start_codes (codec_type_parse);
1523 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001524 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1525 OMX_MAX_STRINGNAME_SIZE)) {
1526 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1527 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1528 eCompressionFormat = OMX_VIDEO_CodingWMV;
1529 codec_type_parse = CODEC_TYPE_VC1;
1530 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1531 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001532 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1533 OMX_MAX_STRINGNAME_SIZE)) {
1534 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1535 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1536 eCompressionFormat = OMX_VIDEO_CodingWMV;
1537 codec_type_parse = CODEC_TYPE_VC1;
1538 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1539 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001540 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1541 OMX_MAX_STRINGNAME_SIZE)) {
1542 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1543 output_capability=V4L2_PIX_FMT_VP8;
1544 eCompressionFormat = OMX_VIDEO_CodingVPX;
1545 codec_type_parse = CODEC_TYPE_VP8;
1546 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001547
Arun Menon906de572013-06-18 17:01:40 -07001548 } else {
1549 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1550 eRet = OMX_ErrorInvalidComponentName;
1551 }
Arun Menon906de572013-06-18 17:01:40 -07001552 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001553
Arun Menon906de572013-06-18 17:01:40 -07001554 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001555 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1556 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1557 if (!client_buffers.set_color_format(dest_color_format)) {
1558 DEBUG_PRINT_ERROR("\n Setting color format failed");
1559 eRet = OMX_ErrorInsufficientResources;
1560 }
1561
Arun Menon906de572013-06-18 17:01:40 -07001562 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001563
Arun Menon906de572013-06-18 17:01:40 -07001564 struct v4l2_capability cap;
1565 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1566 if (ret) {
1567 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
1568 /*TODO: How to handle this case */
1569 } else {
1570 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
1571 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1572 cap.bus_info, cap.version, cap.capabilities);
1573 }
1574 ret=0;
1575 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1576 fdesc.index=0;
1577 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1578 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
1579 fdesc.pixelformat, fdesc.flags);
1580 fdesc.index++;
1581 }
1582 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1583 fdesc.index=0;
1584 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001585
Arun Menon906de572013-06-18 17:01:40 -07001586 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
1587 fdesc.pixelformat, fdesc.flags);
1588 fdesc.index++;
1589 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001590 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001591 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1592 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1593 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1594 fmt.fmt.pix_mp.pixelformat = output_capability;
1595 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1596 if (ret) {
1597 /*TODO: How to handle this case */
1598 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
1599 return OMX_ErrorInsufficientResources;
1600 }
1601 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
1602 if (codec_ambiguous) {
1603 if (output_capability == V4L2_PIX_FMT_DIVX) {
1604 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001605
Arun Menon906de572013-06-18 17:01:40 -07001606 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1607 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1608 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1609 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1610 } else {
1611 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1612 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001613
Arun Menon906de572013-06-18 17:01:40 -07001614 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1615 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1616 if (ret) {
1617 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1618 }
1619 } else {
1620 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1621 }
1622 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001623
Arun Menon906de572013-06-18 17:01:40 -07001624 //Get the hardware capabilities
1625 memset((void *)&frmsize,0,sizeof(frmsize));
1626 frmsize.index = 0;
1627 frmsize.pixel_format = output_capability;
1628 ret = ioctl(drv_ctx.video_driver_fd,
1629 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1630 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1631 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1632 return OMX_ErrorHardware;
1633 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001634
Arun Menon906de572013-06-18 17:01:40 -07001635 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1636 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1637 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1638 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1639 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1640 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001641
Arun Menon906de572013-06-18 17:01:40 -07001642 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1643 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1644 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1645 fmt.fmt.pix_mp.pixelformat = capture_capability;
1646 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1647 if (ret) {
1648 /*TODO: How to handle this case */
1649 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
1650 }
1651 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
1652 if (secure_mode) {
1653 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1654 control.value = 1;
1655 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1656 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1657 if (ret) {
1658 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1659 return OMX_ErrorInsufficientResources;
1660 }
1661 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001662
Arun Menon906de572013-06-18 17:01:40 -07001663 /*Get the Buffer requirements for input and output ports*/
1664 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1665 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1666 if (secure_mode) {
1667 drv_ctx.op_buf.alignment=SZ_1M;
1668 drv_ctx.ip_buf.alignment=SZ_1M;
1669 } else {
1670 drv_ctx.op_buf.alignment=SZ_4K;
1671 drv_ctx.ip_buf.alignment=SZ_4K;
1672 }
1673 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1674 drv_ctx.extradata = 0;
1675 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1676 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1677 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1678 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1679 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001680
Vinay Kalia5713bb32013-01-16 18:39:59 -08001681 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001682#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001683 if (eRet == OMX_ErrorNone && !secure_mode)
1684 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001685#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001686 eRet=get_buffer_req(&drv_ctx.ip_buf);
1687 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1688 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001689 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1690 if (m_frame_parser.mutils == NULL) {
1691 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001692
Arun Menon906de572013-06-18 17:01:40 -07001693 if (m_frame_parser.mutils == NULL) {
1694 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1695 eRet = OMX_ErrorInsufficientResources;
1696 } else {
1697 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1698 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1699 h264_scratch.nFilledLen = 0;
1700 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001701
Arun Menon906de572013-06-18 17:01:40 -07001702 if (h264_scratch.pBuffer == NULL) {
1703 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1704 return OMX_ErrorInsufficientResources;
1705 }
1706 m_frame_parser.mutils->initialize_frame_checking_environment();
1707 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1708 }
1709 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001710
Arun Menon906de572013-06-18 17:01:40 -07001711 h264_parser = new h264_stream_parser();
1712 if (!h264_parser) {
1713 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1714 eRet = OMX_ErrorInsufficientResources;
1715 }
1716 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001717
Arun Menon906de572013-06-18 17:01:40 -07001718 if (pipe(fds)) {
1719 DEBUG_PRINT_ERROR("pipe creation failed\n");
1720 eRet = OMX_ErrorInsufficientResources;
1721 } else {
1722 int temp1[2];
1723 if (fds[0] == 0 || fds[1] == 0) {
1724 if (pipe (temp1)) {
1725 DEBUG_PRINT_ERROR("pipe creation failed\n");
1726 return OMX_ErrorInsufficientResources;
1727 }
1728 //close (fds[0]);
1729 //close (fds[1]);
1730 fds[0] = temp1 [0];
1731 fds[1] = temp1 [1];
1732 }
1733 m_pipe_in = fds[0];
1734 m_pipe_out = fds[1];
1735 msg_thread_created = true;
1736 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001737
Arun Menon906de572013-06-18 17:01:40 -07001738 if (r < 0) {
1739 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1740 msg_thread_created = false;
1741 eRet = OMX_ErrorInsufficientResources;
1742 }
1743 }
1744 }
1745
1746 if (eRet != OMX_ErrorNone) {
1747 DEBUG_PRINT_ERROR("\n Component Init Failed");
1748 } else {
1749 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1750 }
1751 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1752 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001753}
1754
1755/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001756 FUNCTION
1757 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001758
Arun Menon906de572013-06-18 17:01:40 -07001759 DESCRIPTION
1760 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001761
Arun Menon906de572013-06-18 17:01:40 -07001762 PARAMETERS
1763 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001764
Arun Menon906de572013-06-18 17:01:40 -07001765 RETURN VALUE
1766 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001767
Arun Menon906de572013-06-18 17:01:40 -07001768 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001769OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001770(
1771 OMX_IN OMX_HANDLETYPE hComp,
1772 OMX_OUT OMX_STRING componentName,
1773 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1774 OMX_OUT OMX_VERSIONTYPE* specVersion,
1775 OMX_OUT OMX_UUIDTYPE* componentUUID
1776 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001777{
Arun Menon906de572013-06-18 17:01:40 -07001778 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001779 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1780 return OMX_ErrorInvalidState;
1781 }
Arun Menon906de572013-06-18 17:01:40 -07001782 /* TBD -- Return the proper version */
1783 if (specVersion) {
1784 specVersion->nVersion = OMX_SPEC_VERSION;
1785 }
1786 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001787}
1788/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001789 FUNCTION
1790 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001791
Arun Menon906de572013-06-18 17:01:40 -07001792 DESCRIPTION
1793 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001794
Arun Menon906de572013-06-18 17:01:40 -07001795 PARAMETERS
1796 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001797
Arun Menon906de572013-06-18 17:01:40 -07001798 RETURN VALUE
1799 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001800
Arun Menon906de572013-06-18 17:01:40 -07001801 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001802OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001803 OMX_IN OMX_COMMANDTYPE cmd,
1804 OMX_IN OMX_U32 param1,
1805 OMX_IN OMX_PTR cmdData
1806 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001807{
1808 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001809 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001810 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1811 return OMX_ErrorInvalidState;
1812 }
1813 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001814 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
1815 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
1816 "to invalid port: %lu", param1);
1817 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001818 }
1819 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1820 sem_wait(&m_cmd_lock);
1821 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1822 return OMX_ErrorNone;
1823}
1824
1825/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001826 FUNCTION
1827 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001828
Arun Menon906de572013-06-18 17:01:40 -07001829 DESCRIPTION
1830 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001831
Arun Menon906de572013-06-18 17:01:40 -07001832 PARAMETERS
1833 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001834
Arun Menon906de572013-06-18 17:01:40 -07001835 RETURN VALUE
1836 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001837
Arun Menon906de572013-06-18 17:01:40 -07001838 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001839OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001840 OMX_IN OMX_COMMANDTYPE cmd,
1841 OMX_IN OMX_U32 param1,
1842 OMX_IN OMX_PTR cmdData
1843 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001844{
Arun Menon906de572013-06-18 17:01:40 -07001845 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1846 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1847 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001848
Arun Menon906de572013-06-18 17:01:40 -07001849 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1850 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1851 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001852
Arun Menon906de572013-06-18 17:01:40 -07001853 if (cmd == OMX_CommandStateSet) {
1854 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1855 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1856 /***************************/
1857 /* Current State is Loaded */
1858 /***************************/
1859 if (m_state == OMX_StateLoaded) {
1860 if (eState == OMX_StateIdle) {
1861 //if all buffers are allocated or all ports disabled
1862 if (allocate_done() ||
1863 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
1864 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1865 } else {
1866 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1867 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1868 // Skip the event notification
1869 bFlag = 0;
1870 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001871 }
Arun Menon906de572013-06-18 17:01:40 -07001872 /* Requesting transition from Loaded to Loaded */
1873 else if (eState == OMX_StateLoaded) {
1874 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1875 post_event(OMX_EventError,OMX_ErrorSameState,\
1876 OMX_COMPONENT_GENERATE_EVENT);
1877 eRet = OMX_ErrorSameState;
1878 }
1879 /* Requesting transition from Loaded to WaitForResources */
1880 else if (eState == OMX_StateWaitForResources) {
1881 /* Since error is None , we will post an event
1882 at the end of this function definition */
1883 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1884 }
1885 /* Requesting transition from Loaded to Executing */
1886 else if (eState == OMX_StateExecuting) {
1887 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1888 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1889 OMX_COMPONENT_GENERATE_EVENT);
1890 eRet = OMX_ErrorIncorrectStateTransition;
1891 }
1892 /* Requesting transition from Loaded to Pause */
1893 else if (eState == OMX_StatePause) {
1894 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1895 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1896 OMX_COMPONENT_GENERATE_EVENT);
1897 eRet = OMX_ErrorIncorrectStateTransition;
1898 }
1899 /* Requesting transition from Loaded to Invalid */
1900 else if (eState == OMX_StateInvalid) {
1901 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1902 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1903 eRet = OMX_ErrorInvalidState;
1904 } else {
1905 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1906 eState);
1907 eRet = OMX_ErrorBadParameter;
1908 }
1909 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001910
Arun Menon906de572013-06-18 17:01:40 -07001911 /***************************/
1912 /* Current State is IDLE */
1913 /***************************/
1914 else if (m_state == OMX_StateIdle) {
1915 if (eState == OMX_StateLoaded) {
1916 if (release_done()) {
1917 /*
1918 Since error is None , we will post an event at the end
1919 of this function definition
1920 */
1921 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
1922 } else {
1923 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
1924 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1925 // Skip the event notification
1926 bFlag = 0;
1927 }
1928 }
1929 /* Requesting transition from Idle to Executing */
1930 else if (eState == OMX_StateExecuting) {
1931 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1932 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1933 bFlag = 1;
1934 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1935 m_state=OMX_StateExecuting;
1936 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
1937 }
1938 /* Requesting transition from Idle to Idle */
1939 else if (eState == OMX_StateIdle) {
1940 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
1941 post_event(OMX_EventError,OMX_ErrorSameState,\
1942 OMX_COMPONENT_GENERATE_EVENT);
1943 eRet = OMX_ErrorSameState;
1944 }
1945 /* Requesting transition from Idle to WaitForResources */
1946 else if (eState == OMX_StateWaitForResources) {
1947 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
1948 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1949 OMX_COMPONENT_GENERATE_EVENT);
1950 eRet = OMX_ErrorIncorrectStateTransition;
1951 }
1952 /* Requesting transition from Idle to Pause */
1953 else if (eState == OMX_StatePause) {
1954 /*To pause the Video core we need to start the driver*/
1955 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
1956 NULL) < */0) {
1957 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
1958 omx_report_error ();
1959 eRet = OMX_ErrorHardware;
1960 } else {
1961 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1962 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
1963 bFlag = 0;
1964 }
1965 }
1966 /* Requesting transition from Idle to Invalid */
1967 else if (eState == OMX_StateInvalid) {
1968 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
1969 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1970 eRet = OMX_ErrorInvalidState;
1971 } else {
1972 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
1973 eRet = OMX_ErrorBadParameter;
1974 }
1975 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001976
Arun Menon906de572013-06-18 17:01:40 -07001977 /******************************/
1978 /* Current State is Executing */
1979 /******************************/
1980 else if (m_state == OMX_StateExecuting) {
1981 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
1982 /* Requesting transition from Executing to Idle */
1983 if (eState == OMX_StateIdle) {
1984 /* Since error is None , we will post an event
1985 at the end of this function definition
1986 */
1987 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
1988 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1989 if (!sem_posted) {
1990 sem_posted = 1;
1991 sem_post (&m_cmd_lock);
1992 execute_omx_flush(OMX_ALL);
1993 }
1994 bFlag = 0;
1995 }
1996 /* Requesting transition from Executing to Paused */
1997 else if (eState == OMX_StatePause) {
1998 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
1999 m_state = OMX_StatePause;
2000 bFlag = 1;
2001 }
2002 /* Requesting transition from Executing to Loaded */
2003 else if (eState == OMX_StateLoaded) {
2004 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2005 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2006 OMX_COMPONENT_GENERATE_EVENT);
2007 eRet = OMX_ErrorIncorrectStateTransition;
2008 }
2009 /* Requesting transition from Executing to WaitForResources */
2010 else if (eState == OMX_StateWaitForResources) {
2011 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2012 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2013 OMX_COMPONENT_GENERATE_EVENT);
2014 eRet = OMX_ErrorIncorrectStateTransition;
2015 }
2016 /* Requesting transition from Executing to Executing */
2017 else if (eState == OMX_StateExecuting) {
2018 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2019 post_event(OMX_EventError,OMX_ErrorSameState,\
2020 OMX_COMPONENT_GENERATE_EVENT);
2021 eRet = OMX_ErrorSameState;
2022 }
2023 /* Requesting transition from Executing to Invalid */
2024 else if (eState == OMX_StateInvalid) {
2025 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2026 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2027 eRet = OMX_ErrorInvalidState;
2028 } else {
2029 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2030 eRet = OMX_ErrorBadParameter;
2031 }
2032 }
2033 /***************************/
2034 /* Current State is Pause */
2035 /***************************/
2036 else if (m_state == OMX_StatePause) {
2037 /* Requesting transition from Pause to Executing */
2038 if (eState == OMX_StateExecuting) {
2039 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
2040 m_state = OMX_StateExecuting;
2041 bFlag = 1;
2042 }
2043 /* Requesting transition from Pause to Idle */
2044 else if (eState == OMX_StateIdle) {
2045 /* Since error is None , we will post an event
2046 at the end of this function definition */
2047 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2048 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2049 if (!sem_posted) {
2050 sem_posted = 1;
2051 sem_post (&m_cmd_lock);
2052 execute_omx_flush(OMX_ALL);
2053 }
2054 bFlag = 0;
2055 }
2056 /* Requesting transition from Pause to loaded */
2057 else if (eState == OMX_StateLoaded) {
2058 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2059 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2060 OMX_COMPONENT_GENERATE_EVENT);
2061 eRet = OMX_ErrorIncorrectStateTransition;
2062 }
2063 /* Requesting transition from Pause to WaitForResources */
2064 else if (eState == OMX_StateWaitForResources) {
2065 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2066 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2067 OMX_COMPONENT_GENERATE_EVENT);
2068 eRet = OMX_ErrorIncorrectStateTransition;
2069 }
2070 /* Requesting transition from Pause to Pause */
2071 else if (eState == OMX_StatePause) {
2072 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2073 post_event(OMX_EventError,OMX_ErrorSameState,\
2074 OMX_COMPONENT_GENERATE_EVENT);
2075 eRet = OMX_ErrorSameState;
2076 }
2077 /* Requesting transition from Pause to Invalid */
2078 else if (eState == OMX_StateInvalid) {
2079 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2080 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2081 eRet = OMX_ErrorInvalidState;
2082 } else {
2083 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2084 eRet = OMX_ErrorBadParameter;
2085 }
2086 }
2087 /***************************/
2088 /* Current State is WaitForResources */
2089 /***************************/
2090 else if (m_state == OMX_StateWaitForResources) {
2091 /* Requesting transition from WaitForResources to Loaded */
2092 if (eState == OMX_StateLoaded) {
2093 /* Since error is None , we will post an event
2094 at the end of this function definition */
2095 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2096 }
2097 /* Requesting transition from WaitForResources to WaitForResources */
2098 else if (eState == OMX_StateWaitForResources) {
2099 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2100 post_event(OMX_EventError,OMX_ErrorSameState,
2101 OMX_COMPONENT_GENERATE_EVENT);
2102 eRet = OMX_ErrorSameState;
2103 }
2104 /* Requesting transition from WaitForResources to Executing */
2105 else if (eState == OMX_StateExecuting) {
2106 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2107 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2108 OMX_COMPONENT_GENERATE_EVENT);
2109 eRet = OMX_ErrorIncorrectStateTransition;
2110 }
2111 /* Requesting transition from WaitForResources to Pause */
2112 else if (eState == OMX_StatePause) {
2113 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2114 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2115 OMX_COMPONENT_GENERATE_EVENT);
2116 eRet = OMX_ErrorIncorrectStateTransition;
2117 }
2118 /* Requesting transition from WaitForResources to Invalid */
2119 else if (eState == OMX_StateInvalid) {
2120 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2121 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2122 eRet = OMX_ErrorInvalidState;
2123 }
2124 /* Requesting transition from WaitForResources to Loaded -
2125 is NOT tested by Khronos TS */
2126
2127 } else {
2128 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2129 eRet = OMX_ErrorBadParameter;
2130 }
2131 }
2132 /********************************/
2133 /* Current State is Invalid */
2134 /*******************************/
2135 else if (m_state == OMX_StateInvalid) {
2136 /* State Transition from Inavlid to any state */
2137 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2138 || OMX_StateIdle || OMX_StateExecuting
2139 || OMX_StatePause || OMX_StateInvalid)) {
2140 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2141 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2142 OMX_COMPONENT_GENERATE_EVENT);
2143 eRet = OMX_ErrorInvalidState;
2144 }
2145 } else if (cmd == OMX_CommandFlush) {
2146 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
2147 "with param1: %lu", param1);
2148 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2149 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2150 }
2151 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2152 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2153 }
2154 if (!sem_posted) {
2155 sem_posted = 1;
2156 DEBUG_PRINT_LOW("\n Set the Semaphore");
2157 sem_post (&m_cmd_lock);
2158 execute_omx_flush(param1);
2159 }
2160 bFlag = 0;
2161 } else if ( cmd == OMX_CommandPortEnable) {
2162 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
2163 "with param1: %lu", param1);
2164 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2165 m_inp_bEnabled = OMX_TRUE;
2166
2167 if ( (m_state == OMX_StateLoaded &&
2168 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2169 || allocate_input_done()) {
2170 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2171 OMX_COMPONENT_GENERATE_EVENT);
2172 } else {
2173 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2174 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2175 // Skip the event notification
2176 bFlag = 0;
2177 }
2178 }
2179 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2180 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2181 m_out_bEnabled = OMX_TRUE;
2182
2183 if ( (m_state == OMX_StateLoaded &&
2184 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2185 || (allocate_output_done())) {
2186 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2187 OMX_COMPONENT_GENERATE_EVENT);
2188
2189 } else {
2190 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2191 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2192 // Skip the event notification
2193 bFlag = 0;
2194 }
2195 }
2196 } else if (cmd == OMX_CommandPortDisable) {
2197 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
2198 "with param1: %lu", param1);
2199 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2200 m_inp_bEnabled = OMX_FALSE;
2201 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2202 && release_input_done()) {
2203 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2204 OMX_COMPONENT_GENERATE_EVENT);
2205 } else {
2206 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2207 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2208 if (!sem_posted) {
2209 sem_posted = 1;
2210 sem_post (&m_cmd_lock);
2211 }
2212 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2213 }
2214
2215 // Skip the event notification
2216 bFlag = 0;
2217 }
2218 }
2219 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2220 m_out_bEnabled = OMX_FALSE;
2221 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2222 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2223 && release_output_done()) {
2224 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2225 OMX_COMPONENT_GENERATE_EVENT);
2226 } else {
2227 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2228 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2229 if (!sem_posted) {
2230 sem_posted = 1;
2231 sem_post (&m_cmd_lock);
2232 }
2233 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2234 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2235 }
2236 // Skip the event notification
2237 bFlag = 0;
2238
2239 }
2240 }
2241 } else {
2242 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2243 eRet = OMX_ErrorNotImplemented;
2244 }
2245 if (eRet == OMX_ErrorNone && bFlag) {
2246 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2247 }
2248 if (!sem_posted) {
2249 sem_post(&m_cmd_lock);
2250 }
2251
2252 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002253}
2254
2255/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002256 FUNCTION
2257 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002258
Arun Menon906de572013-06-18 17:01:40 -07002259 DESCRIPTION
2260 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002261
Arun Menon906de572013-06-18 17:01:40 -07002262 PARAMETERS
2263 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002264
Arun Menon906de572013-06-18 17:01:40 -07002265 RETURN VALUE
2266 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002267
Arun Menon906de572013-06-18 17:01:40 -07002268 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002269bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2270{
Arun Menon906de572013-06-18 17:01:40 -07002271 bool bRet = false;
2272 struct v4l2_plane plane;
2273 struct v4l2_buffer v4l2_buf;
2274 struct v4l2_decoder_cmd dec;
2275 DEBUG_PRINT_LOW("in %s, flushing %d", __func__, flushType);
2276 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2277 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002278
Arun Menon906de572013-06-18 17:01:40 -07002279 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002280
Arun Menon906de572013-06-18 17:01:40 -07002281 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2282 output_flush_progress = true;
2283 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2284 } else {
2285 /* XXX: The driver/hardware does not support flushing of individual ports
2286 * in all states. So we pretty much need to flush both ports internally,
2287 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2288 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2289 * we automatically omit sending the FLUSH done for the "opposite" port. */
2290 input_flush_progress = true;
2291 output_flush_progress = true;
2292 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2293 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002294
Arun Menon906de572013-06-18 17:01:40 -07002295 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
2296 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
2297 bRet = false;
2298 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002299
Arun Menon906de572013-06-18 17:01:40 -07002300 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002301}
2302/*=========================================================================
2303FUNCTION : execute_output_flush
2304
2305DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002306Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002307
2308PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002309None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002310
2311RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002312true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002313==========================================================================*/
2314bool omx_vdec::execute_output_flush()
2315{
Arun Menon906de572013-06-18 17:01:40 -07002316 unsigned p1 = 0; // Parameter - 1
2317 unsigned p2 = 0; // Parameter - 2
2318 unsigned ident = 0;
2319 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002320
Arun Menon906de572013-06-18 17:01:40 -07002321 /*Generate FBD for all Buffers in the FTBq*/
2322 pthread_mutex_lock(&m_lock);
2323 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2324 while (m_ftb_q.m_size) {
2325 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2326 m_ftb_q.m_size,pending_output_buffers);
2327 m_ftb_q.pop_entry(&p1,&p2,&ident);
2328 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
2329 if (ident == m_fill_output_msg ) {
2330 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2331 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2332 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2333 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002334 }
Arun Menon906de572013-06-18 17:01:40 -07002335 pthread_mutex_unlock(&m_lock);
2336 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002337
Arun Menon906de572013-06-18 17:01:40 -07002338 if (arbitrary_bytes) {
2339 prev_ts = LLONG_MAX;
2340 rst_prev_ts = true;
2341 }
2342 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2343 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002344}
2345/*=========================================================================
2346FUNCTION : execute_input_flush
2347
2348DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002349Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002350
2351PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002352None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002353
2354RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002355true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002356==========================================================================*/
2357bool omx_vdec::execute_input_flush()
2358{
Arun Menon906de572013-06-18 17:01:40 -07002359 unsigned i =0;
2360 unsigned p1 = 0; // Parameter - 1
2361 unsigned p2 = 0; // Parameter - 2
2362 unsigned ident = 0;
2363 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002364
Arun Menon906de572013-06-18 17:01:40 -07002365 /*Generate EBD for all Buffers in the ETBq*/
2366 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002367
Arun Menon906de572013-06-18 17:01:40 -07002368 pthread_mutex_lock(&m_lock);
2369 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2370 while (m_etb_q.m_size) {
2371 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002372
Arun Menon906de572013-06-18 17:01:40 -07002373 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2374 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2375 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2376 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2377 pending_input_buffers++;
2378 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2379 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2380 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2381 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
2382 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2383 (OMX_BUFFERHEADERTYPE *)p1);
2384 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2385 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002386 }
Arun Menon906de572013-06-18 17:01:40 -07002387 time_stamp_dts.flush_timestamp();
2388 /*Check if Heap Buffers are to be flushed*/
2389 if (arbitrary_bytes && !(codec_config_flag)) {
2390 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2391 h264_scratch.nFilledLen = 0;
2392 nal_count = 0;
2393 look_ahead_nal = false;
2394 frame_count = 0;
2395 h264_last_au_ts = LLONG_MAX;
2396 h264_last_au_flags = 0;
2397 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2398 m_demux_entries = 0;
2399 DEBUG_PRINT_LOW("\n Initialize parser");
2400 if (m_frame_parser.mutils) {
2401 m_frame_parser.mutils->initialize_frame_checking_environment();
2402 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002403
Arun Menon906de572013-06-18 17:01:40 -07002404 while (m_input_pending_q.m_size) {
2405 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2406 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2407 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002408
Arun Menon906de572013-06-18 17:01:40 -07002409 if (psource_frame) {
2410 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2411 psource_frame = NULL;
2412 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002413
Arun Menon906de572013-06-18 17:01:40 -07002414 if (pdest_frame) {
2415 pdest_frame->nFilledLen = 0;
2416 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2417 (unsigned int)NULL);
2418 pdest_frame = NULL;
2419 }
2420 m_frame_parser.flush();
2421 } else if (codec_config_flag) {
2422 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2423 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002424 }
Arun Menon906de572013-06-18 17:01:40 -07002425 pthread_mutex_unlock(&m_lock);
2426 input_flush_progress = false;
2427 if (!arbitrary_bytes) {
2428 prev_ts = LLONG_MAX;
2429 rst_prev_ts = true;
2430 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002431#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002432 if (m_debug_timestamp) {
2433 m_timestamp_list.reset_ts_list();
2434 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002435#endif
Arun Menon906de572013-06-18 17:01:40 -07002436 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2437 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002438}
2439
2440
2441/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002442 FUNCTION
2443 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002444
Arun Menon906de572013-06-18 17:01:40 -07002445 DESCRIPTION
2446 Send the event to decoder pipe. This is needed to generate the callbacks
2447 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002448
Arun Menon906de572013-06-18 17:01:40 -07002449 PARAMETERS
2450 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002451
Arun Menon906de572013-06-18 17:01:40 -07002452 RETURN VALUE
2453 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002454
Arun Menon906de572013-06-18 17:01:40 -07002455 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002456bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002457 unsigned int p2,
2458 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002459{
Arun Menon906de572013-06-18 17:01:40 -07002460 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002461
2462
Arun Menon906de572013-06-18 17:01:40 -07002463 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002464
Arun Menon906de572013-06-18 17:01:40 -07002465 if (id == m_fill_output_msg ||
2466 id == OMX_COMPONENT_GENERATE_FBD) {
2467 m_ftb_q.insert_entry(p1,p2,id);
2468 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2469 id == OMX_COMPONENT_GENERATE_EBD ||
2470 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2471 m_etb_q.insert_entry(p1,p2,id);
2472 } else {
2473 m_cmd_q.insert_entry(p1,p2,id);
2474 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002475
Arun Menon906de572013-06-18 17:01:40 -07002476 bRet = true;
2477 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2478 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002479
Arun Menon906de572013-06-18 17:01:40 -07002480 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002481
Arun Menon906de572013-06-18 17:01:40 -07002482 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002483}
2484
2485OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2486{
Arun Menon906de572013-06-18 17:01:40 -07002487 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2488 if (!profileLevelType)
2489 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002490
Arun Menon906de572013-06-18 17:01:40 -07002491 if (profileLevelType->nPortIndex == 0) {
2492 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2493 if (profileLevelType->nProfileIndex == 0) {
2494 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2495 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002496
Arun Menon906de572013-06-18 17:01:40 -07002497 } else if (profileLevelType->nProfileIndex == 1) {
2498 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2499 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2500 } else if (profileLevelType->nProfileIndex == 2) {
2501 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2502 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2503 } else {
2504 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
2505 profileLevelType->nProfileIndex);
2506 eRet = OMX_ErrorNoMore;
2507 }
2508 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2509 if (profileLevelType->nProfileIndex == 0) {
2510 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2511 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2512 } else {
2513 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2514 eRet = OMX_ErrorNoMore;
2515 }
2516 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2517 if (profileLevelType->nProfileIndex == 0) {
2518 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2519 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2520 } else if (profileLevelType->nProfileIndex == 1) {
2521 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2522 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2523 } else {
2524 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2525 eRet = OMX_ErrorNoMore;
2526 }
2527 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2528 eRet = OMX_ErrorNoMore;
2529 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2530 if (profileLevelType->nProfileIndex == 0) {
2531 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2532 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2533 } else if (profileLevelType->nProfileIndex == 1) {
2534 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2535 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2536 } else {
2537 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2538 eRet = OMX_ErrorNoMore;
2539 }
2540 } else {
2541 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s\n", drv_ctx.kind);
2542 eRet = OMX_ErrorNoMore;
2543 }
2544 } else {
2545 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex);
2546 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002547 }
Arun Menon906de572013-06-18 17:01:40 -07002548 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002549}
2550
2551/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002552 FUNCTION
2553 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002554
Arun Menon906de572013-06-18 17:01:40 -07002555 DESCRIPTION
2556 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002557
Arun Menon906de572013-06-18 17:01:40 -07002558 PARAMETERS
2559 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002560
Arun Menon906de572013-06-18 17:01:40 -07002561 RETURN VALUE
2562 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002563
Arun Menon906de572013-06-18 17:01:40 -07002564 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002565OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002566 OMX_IN OMX_INDEXTYPE paramIndex,
2567 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002568{
2569 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2570
2571 DEBUG_PRINT_LOW("get_parameter: \n");
Arun Menon906de572013-06-18 17:01:40 -07002572 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002573 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2574 return OMX_ErrorInvalidState;
2575 }
Arun Menon906de572013-06-18 17:01:40 -07002576 if (paramData == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002577 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2578 return OMX_ErrorBadParameter;
2579 }
Arun Menon906de572013-06-18 17:01:40 -07002580 switch ((unsigned long)paramIndex) {
2581 case OMX_IndexParamPortDefinition: {
2582 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2583 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2584 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2585 eRet = update_portdef(portDefn);
2586 if (eRet == OMX_ErrorNone)
2587 m_port_def = *portDefn;
2588 break;
2589 }
2590 case OMX_IndexParamVideoInit: {
2591 OMX_PORT_PARAM_TYPE *portParamType =
2592 (OMX_PORT_PARAM_TYPE *) paramData;
2593 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002594
Arun Menon906de572013-06-18 17:01:40 -07002595 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2596 portParamType->nSize = sizeof(portParamType);
2597 portParamType->nPorts = 2;
2598 portParamType->nStartPortNumber = 0;
2599 break;
2600 }
2601 case OMX_IndexParamVideoPortFormat: {
2602 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2603 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2604 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002605
Arun Menon906de572013-06-18 17:01:40 -07002606 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2607 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002608
Arun Menon906de572013-06-18 17:01:40 -07002609 if (0 == portFmt->nPortIndex) {
2610 if (0 == portFmt->nIndex) {
2611 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2612 portFmt->eCompressionFormat = eCompressionFormat;
2613 } else {
2614 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2615 " NoMore compression formats\n");
2616 eRet = OMX_ErrorNoMore;
2617 }
2618 } else if (1 == portFmt->nPortIndex) {
2619 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002620
Arun Menon906de572013-06-18 17:01:40 -07002621 if (0 == portFmt->nIndex)
2622 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2623 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2624 else if (1 == portFmt->nIndex)
2625 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2626 else {
2627 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2628 " NoMore Color formats\n");
2629 eRet = OMX_ErrorNoMore;
2630 }
2631 DEBUG_PRINT_LOW("returning %d\n", portFmt->eColorFormat);
2632 } else {
2633 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2634 (int)portFmt->nPortIndex);
2635 eRet = OMX_ErrorBadPortIndex;
2636 }
2637 break;
2638 }
2639 /*Component should support this port definition*/
2640 case OMX_IndexParamAudioInit: {
2641 OMX_PORT_PARAM_TYPE *audioPortParamType =
2642 (OMX_PORT_PARAM_TYPE *) paramData;
2643 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2644 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2645 audioPortParamType->nSize = sizeof(audioPortParamType);
2646 audioPortParamType->nPorts = 0;
2647 audioPortParamType->nStartPortNumber = 0;
2648 break;
2649 }
2650 /*Component should support this port definition*/
2651 case OMX_IndexParamImageInit: {
2652 OMX_PORT_PARAM_TYPE *imagePortParamType =
2653 (OMX_PORT_PARAM_TYPE *) paramData;
2654 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2655 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2656 imagePortParamType->nSize = sizeof(imagePortParamType);
2657 imagePortParamType->nPorts = 0;
2658 imagePortParamType->nStartPortNumber = 0;
2659 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002660
Arun Menon906de572013-06-18 17:01:40 -07002661 }
2662 /*Component should support this port definition*/
2663 case OMX_IndexParamOtherInit: {
2664 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2665 paramIndex);
2666 eRet =OMX_ErrorUnsupportedIndex;
2667 break;
2668 }
2669 case OMX_IndexParamStandardComponentRole: {
2670 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2671 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2672 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2673 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002674
Arun Menon906de572013-06-18 17:01:40 -07002675 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2676 paramIndex);
2677 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2678 OMX_MAX_STRINGNAME_SIZE);
2679 break;
2680 }
2681 /* Added for parameter test */
2682 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002683
Arun Menon906de572013-06-18 17:01:40 -07002684 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2685 (OMX_PRIORITYMGMTTYPE *) paramData;
2686 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2687 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2688 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002689
Arun Menon906de572013-06-18 17:01:40 -07002690 break;
2691 }
2692 /* Added for parameter test */
2693 case OMX_IndexParamCompBufferSupplier: {
2694 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2695 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2696 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002697
Arun Menon906de572013-06-18 17:01:40 -07002698 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2699 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2700 if (0 == bufferSupplierType->nPortIndex)
2701 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2702 else if (1 == bufferSupplierType->nPortIndex)
2703 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2704 else
2705 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002706
2707
Arun Menon906de572013-06-18 17:01:40 -07002708 break;
2709 }
2710 case OMX_IndexParamVideoAvc: {
2711 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2712 paramIndex);
2713 break;
2714 }
2715 case OMX_IndexParamVideoH263: {
2716 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2717 paramIndex);
2718 break;
2719 }
2720 case OMX_IndexParamVideoMpeg4: {
2721 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2722 paramIndex);
2723 break;
2724 }
2725 case OMX_IndexParamVideoMpeg2: {
2726 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2727 paramIndex);
2728 break;
2729 }
2730 case OMX_IndexParamVideoProfileLevelQuerySupported: {
2731 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2732 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2733 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2734 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2735 break;
2736 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002737#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002738 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
2739 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2740 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2741 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002742
Arun Menon906de572013-06-18 17:01:40 -07002743 if (secure_mode) {
2744 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2745 GRALLOC_USAGE_PRIVATE_UNCACHED);
2746 } else {
2747 nativeBuffersUsage->nUsage =
2748 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2749 GRALLOC_USAGE_PRIVATE_UNCACHED);
2750 }
2751 } else {
2752 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
2753 eRet = OMX_ErrorBadParameter;
2754 }
2755 }
2756 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002757#endif
2758
Arun Menon906de572013-06-18 17:01:40 -07002759 default: {
2760 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2761 eRet =OMX_ErrorUnsupportedIndex;
2762 }
2763
Shalaj Jain273b3e02012-06-22 19:08:03 -07002764 }
2765
Arun Menon906de572013-06-18 17:01:40 -07002766 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
2767 drv_ctx.video_resolution.frame_width,
2768 drv_ctx.video_resolution.frame_height,
2769 drv_ctx.video_resolution.stride,
2770 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002771
Arun Menon906de572013-06-18 17:01:40 -07002772 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002773}
2774
2775#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2776OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2777{
2778 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2779 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2780 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2781
Arun Menon906de572013-06-18 17:01:40 -07002782 if ((params == NULL) ||
2783 (params->nativeBuffer == NULL) ||
2784 (params->nativeBuffer->handle == NULL) ||
2785 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002786 return OMX_ErrorBadParameter;
2787 m_use_android_native_buffers = OMX_TRUE;
2788 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2789 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002790 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 -07002791 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002792 if (!secure_mode) {
2793 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002794 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002795 if (buffer == MAP_FAILED) {
2796 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2797 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002798 }
2799 }
2800 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2801 } else {
2802 eRet = OMX_ErrorBadParameter;
2803 }
2804 return eRet;
2805}
2806#endif
2807/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002808 FUNCTION
2809 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002810
Arun Menon906de572013-06-18 17:01:40 -07002811 DESCRIPTION
2812 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002813
Arun Menon906de572013-06-18 17:01:40 -07002814 PARAMETERS
2815 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002816
Arun Menon906de572013-06-18 17:01:40 -07002817 RETURN VALUE
2818 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002819
Arun Menon906de572013-06-18 17:01:40 -07002820 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002821OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002822 OMX_IN OMX_INDEXTYPE paramIndex,
2823 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002824{
2825 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002826 int ret=0;
2827 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002828 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002829 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
2830 return OMX_ErrorInvalidState;
2831 }
Arun Menon906de572013-06-18 17:01:40 -07002832 if (paramData == NULL) {
2833 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
2834 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002835 }
Arun Menon906de572013-06-18 17:01:40 -07002836 if ((m_state != OMX_StateLoaded) &&
2837 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2838 (m_out_bEnabled == OMX_TRUE) &&
2839 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2840 (m_inp_bEnabled == OMX_TRUE)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002841 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
2842 return OMX_ErrorIncorrectStateOperation;
2843 }
Arun Menon906de572013-06-18 17:01:40 -07002844 switch ((unsigned long)paramIndex) {
2845 case OMX_IndexParamPortDefinition: {
2846 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2847 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2848 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2849 //been called.
2850 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
2851 (int)portDefn->format.video.nFrameHeight,
2852 (int)portDefn->format.video.nFrameWidth);
2853 if (OMX_DirOutput == portDefn->eDir) {
2854 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
2855 m_display_id = portDefn->format.video.pNativeWindow;
2856 unsigned int buffer_size;
2857 if (!client_buffers.get_buffer_req(buffer_size)) {
2858 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
2859 eRet = OMX_ErrorBadParameter;
2860 } else {
2861 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
2862 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
2863 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
2864 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
2865 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
2866 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
2867 drv_ctx.extradata_info.buffer_size;
2868 eRet = set_buffer_req(&drv_ctx.op_buf);
2869 if (eRet == OMX_ErrorNone)
2870 m_port_def = *portDefn;
2871 } else {
2872 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
2873 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
2874 portDefn->nBufferCountActual, portDefn->nBufferSize);
2875 eRet = OMX_ErrorBadParameter;
2876 }
2877 }
2878 } else if (OMX_DirInput == portDefn->eDir) {
2879 bool port_format_changed = false;
2880 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
2881 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
2882 // Frame rate only should be set if this is a "known value" or to
2883 // activate ts prediction logic (arbitrary mode only) sending input
2884 // timestamps with max value (LLONG_MAX).
2885 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
2886 portDefn->format.video.xFramerate >> 16);
2887 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
2888 drv_ctx.frame_rate.fps_denominator);
2889 if (!drv_ctx.frame_rate.fps_numerator) {
2890 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
2891 drv_ctx.frame_rate.fps_numerator = 30;
2892 }
2893 if (drv_ctx.frame_rate.fps_denominator)
2894 drv_ctx.frame_rate.fps_numerator = (int)
2895 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
2896 drv_ctx.frame_rate.fps_denominator = 1;
2897 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
2898 drv_ctx.frame_rate.fps_numerator;
2899 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
2900 frm_int, drv_ctx.frame_rate.fps_numerator /
2901 (float)drv_ctx.frame_rate.fps_denominator);
2902 }
2903 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
2904 if (drv_ctx.video_resolution.frame_height !=
2905 portDefn->format.video.nFrameHeight ||
2906 drv_ctx.video_resolution.frame_width !=
2907 portDefn->format.video.nFrameWidth) {
2908 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
2909 portDefn->format.video.nFrameWidth,
2910 portDefn->format.video.nFrameHeight);
2911 port_format_changed = true;
2912 if (portDefn->format.video.nFrameHeight != 0x0 &&
2913 portDefn->format.video.nFrameWidth != 0x0) {
2914 update_resolution(portDefn->format.video.nFrameWidth,
2915 portDefn->format.video.nFrameHeight,
2916 portDefn->format.video.nFrameWidth,
2917 portDefn->format.video.nFrameHeight);
2918 eRet = is_video_session_supported();
2919 if (eRet)
2920 break;
2921 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2922 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2923 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2924 fmt.fmt.pix_mp.pixelformat = output_capability;
2925 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);
2926 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2927 if (ret) {
2928 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2929 eRet = OMX_ErrorUnsupportedSetting;
2930 } else
2931 eRet = get_buffer_req(&drv_ctx.op_buf);
2932 }
2933 }
2934 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
2935 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
2936 port_format_changed = true;
2937 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
2938 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
2939 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
2940 (~(buffer_prop->alignment - 1));
2941 eRet = set_buffer_req(buffer_prop);
2942 }
2943 if (false == port_format_changed) {
2944 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
2945 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
2946 portDefn->nBufferCountActual, portDefn->nBufferSize);
2947 eRet = OMX_ErrorBadParameter;
2948 }
2949 } else if (portDefn->eDir == OMX_DirMax) {
2950 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
2951 (int)portDefn->nPortIndex);
2952 eRet = OMX_ErrorBadPortIndex;
2953 }
2954 }
2955 break;
2956 case OMX_IndexParamVideoPortFormat: {
2957 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2958 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2959 int ret=0;
2960 struct v4l2_format fmt;
2961 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
2962 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002963
Arun Menon906de572013-06-18 17:01:40 -07002964 if (1 == portFmt->nPortIndex) {
2965 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2966 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2967 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2968 fmt.fmt.pix_mp.pixelformat = capture_capability;
2969 enum vdec_output_fromat op_format;
2970 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
2971 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
2972 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
2973 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
2974 else if (portFmt->eColorFormat ==
2975 (OMX_COLOR_FORMATTYPE)
2976 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
2977 op_format = VDEC_YUV_FORMAT_TILE_4x2;
2978 else
2979 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002980
Arun Menon906de572013-06-18 17:01:40 -07002981 if (eRet == OMX_ErrorNone) {
2982 drv_ctx.output_format = op_format;
2983 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2984 if (ret) {
2985 DEBUG_PRINT_ERROR("\n Set output format failed");
2986 eRet = OMX_ErrorUnsupportedSetting;
2987 /*TODO: How to handle this case */
2988 } else {
2989 eRet = get_buffer_req(&drv_ctx.op_buf);
2990 }
2991 }
2992 if (eRet == OMX_ErrorNone) {
2993 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
2994 DEBUG_PRINT_ERROR("\n Set color format failed");
2995 eRet = OMX_ErrorBadParameter;
2996 }
2997 }
2998 }
2999 }
3000 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003001
Arun Menon906de572013-06-18 17:01:40 -07003002 case OMX_QcomIndexPortDefn: {
3003 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3004 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
3005 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
3006 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003007
Arun Menon906de572013-06-18 17:01:40 -07003008 /* Input port */
3009 if (portFmt->nPortIndex == 0) {
3010 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3011 if (secure_mode) {
3012 arbitrary_bytes = false;
3013 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3014 eRet = OMX_ErrorUnsupportedSetting;
3015 } else {
3016 arbitrary_bytes = true;
3017 }
3018 } else if (portFmt->nFramePackingFormat ==
3019 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3020 arbitrary_bytes = false;
3021 } else {
3022 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
3023 portFmt->nFramePackingFormat);
3024 eRet = OMX_ErrorUnsupportedSetting;
3025 }
3026 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3027 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3028 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3029 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3030 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3031 m_out_mem_region_smi = OMX_TRUE;
3032 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3033 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3034 m_use_output_pmem = OMX_TRUE;
3035 }
3036 }
3037 }
3038 }
3039 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003040
Arun Menon906de572013-06-18 17:01:40 -07003041 case OMX_IndexParamStandardComponentRole: {
3042 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3043 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3044 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3045 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003046
Arun Menon906de572013-06-18 17:01:40 -07003047 if ((m_state == OMX_StateLoaded)&&
3048 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3049 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3050 } else {
3051 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3052 return OMX_ErrorIncorrectStateOperation;
3053 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003054
Arun Menon906de572013-06-18 17:01:40 -07003055 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3056 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3057 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3058 } else {
3059 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3060 eRet =OMX_ErrorUnsupportedSetting;
3061 }
3062 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3063 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3064 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3065 } else {
3066 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3067 eRet = OMX_ErrorUnsupportedSetting;
3068 }
3069 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3070 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3071 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3072 } else {
3073 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3074 eRet =OMX_ErrorUnsupportedSetting;
3075 }
3076 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3077 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3078 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3079 } else {
3080 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3081 eRet = OMX_ErrorUnsupportedSetting;
3082 }
3083 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3084 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3085 ) {
3086 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3087 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3088 } else {
3089 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3090 eRet =OMX_ErrorUnsupportedSetting;
3091 }
3092 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3093 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3094 ) {
3095 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3096 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3097 } else {
3098 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3099 eRet =OMX_ErrorUnsupportedSetting;
3100 }
3101 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3102 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3103 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3104 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3105 } else {
3106 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3107 eRet = OMX_ErrorUnsupportedSetting;
3108 }
3109 } else {
3110 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3111 eRet = OMX_ErrorInvalidComponentName;
3112 }
3113 break;
3114 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003115
Arun Menon906de572013-06-18 17:01:40 -07003116 case OMX_IndexParamPriorityMgmt: {
3117 if (m_state != OMX_StateLoaded) {
3118 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3119 return OMX_ErrorIncorrectStateOperation;
3120 }
3121 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
3122 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
3123 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003124
Arun Menon906de572013-06-18 17:01:40 -07003125 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
3126 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003127
Arun Menon906de572013-06-18 17:01:40 -07003128 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3129 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003130
Arun Menon906de572013-06-18 17:01:40 -07003131 break;
3132 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003133
Arun Menon906de572013-06-18 17:01:40 -07003134 case OMX_IndexParamCompBufferSupplier: {
3135 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3136 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3137 bufferSupplierType->eBufferSupplier);
3138 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3139 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003140
Arun Menon906de572013-06-18 17:01:40 -07003141 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003142
Arun Menon906de572013-06-18 17:01:40 -07003143 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003144
Arun Menon906de572013-06-18 17:01:40 -07003145 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003146
Arun Menon906de572013-06-18 17:01:40 -07003147 }
3148 case OMX_IndexParamVideoAvc: {
3149 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3150 paramIndex);
3151 break;
3152 }
3153 case OMX_IndexParamVideoH263: {
3154 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3155 paramIndex);
3156 break;
3157 }
3158 case OMX_IndexParamVideoMpeg4: {
3159 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3160 paramIndex);
3161 break;
3162 }
3163 case OMX_IndexParamVideoMpeg2: {
3164 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3165 paramIndex);
3166 break;
3167 }
3168 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3169 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3170 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3171 struct v4l2_control control;
3172 int pic_order,rc=0;
3173 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3174 pictureOrder->eOutputPictureOrder);
3175 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3176 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3177 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3178 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3179 time_stamp_dts.set_timestamp_reorder_mode(false);
3180 } else
3181 eRet = OMX_ErrorBadParameter;
3182 if (eRet == OMX_ErrorNone) {
3183 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3184 control.value = pic_order;
3185 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3186 if (rc) {
3187 DEBUG_PRINT_ERROR("\n Set picture order failed");
3188 eRet = OMX_ErrorUnsupportedSetting;
3189 }
3190 }
3191 break;
3192 }
3193 case OMX_QcomIndexParamConcealMBMapExtraData:
3194 if (!secure_mode)
3195 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3196 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3197 else {
3198 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3199 eRet = OMX_ErrorUnsupportedSetting;
3200 }
3201 break;
3202 case OMX_QcomIndexParamFrameInfoExtraData: {
3203 if (!secure_mode)
3204 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3205 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3206 else {
3207 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3208 eRet = OMX_ErrorUnsupportedSetting;
3209 }
3210 break;
3211 }
3212 case OMX_QcomIndexParamInterlaceExtraData:
3213 if (!secure_mode)
3214 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3215 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3216 else {
3217 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3218 eRet = OMX_ErrorUnsupportedSetting;
3219 }
3220 break;
3221 case OMX_QcomIndexParamH264TimeInfo:
3222 if (!secure_mode)
3223 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3224 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3225 else {
3226 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3227 eRet = OMX_ErrorUnsupportedSetting;
3228 }
3229 break;
3230 case OMX_QcomIndexParamVideoDivx: {
3231 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3232 }
3233 break;
3234 case OMX_QcomIndexPlatformPvt: {
3235 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3236 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3237 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3238 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3239 eRet = OMX_ErrorUnsupportedSetting;
3240 } else {
3241 m_out_pvt_entry_pmem = OMX_TRUE;
3242 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3243 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3244 m_use_output_pmem = OMX_TRUE;
3245 }
3246 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003247
Arun Menon906de572013-06-18 17:01:40 -07003248 }
3249 break;
3250 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3251 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3252 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3253 struct v4l2_control control;
3254 int rc;
3255 drv_ctx.idr_only_decoding = 1;
3256 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3257 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3258 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3259 if (rc) {
3260 DEBUG_PRINT_ERROR("\n Set picture order failed");
3261 eRet = OMX_ErrorUnsupportedSetting;
3262 } else {
3263 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3264 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3265 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3266 if (rc) {
3267 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3268 eRet = OMX_ErrorUnsupportedSetting;
3269 }
3270 /*Setting sync frame decoding on driver might change buffer
3271 * requirements so update them here*/
3272 if (get_buffer_req(&drv_ctx.ip_buf)) {
3273 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer i/p requirements");
3274 eRet = OMX_ErrorUnsupportedSetting;
3275 }
3276 if (get_buffer_req(&drv_ctx.op_buf)) {
3277 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer o/p requirements");
3278 eRet = OMX_ErrorUnsupportedSetting;
3279 }
3280 }
3281 }
3282 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003283
Arun Menon906de572013-06-18 17:01:40 -07003284 case OMX_QcomIndexParamIndexExtraDataType: {
3285 if (!secure_mode) {
3286 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3287 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3288 (extradataIndexType->bEnabled == OMX_TRUE) &&
3289 (extradataIndexType->nPortIndex == 1)) {
3290 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
3291 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003292
Arun Menon906de572013-06-18 17:01:40 -07003293 }
3294 }
3295 }
3296 break;
3297 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003298#ifndef SMOOTH_STREAMING_DISABLED
Arun Menon906de572013-06-18 17:01:40 -07003299 struct v4l2_control control;
3300 struct v4l2_format fmt;
3301 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3302 control.value = 1;
3303 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3304 if (rc < 0) {
3305 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3306 eRet = OMX_ErrorHardware;
3307 }
Arun Menonbc0922f2013-06-24 13:02:15 -07003308#else
Arun Menon906de572013-06-18 17:01:40 -07003309 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003310#endif
Arun Menon906de572013-06-18 17:01:40 -07003311 }
3312 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003313#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003314 /* Need to allow following two set_parameters even in Idle
3315 * state. This is ANDROID architecture which is not in sync
3316 * with openmax standard. */
3317 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3318 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3319 if (enableNativeBuffers) {
3320 m_enable_android_native_buffers = enableNativeBuffers->enable;
3321 }
3322 }
3323 break;
3324 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3325 eRet = use_android_native_buffer(hComp, paramData);
3326 }
3327 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003328#endif
Arun Menon906de572013-06-18 17:01:40 -07003329 case OMX_QcomIndexParamEnableTimeStampReorder: {
3330 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3331 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3332 if (reorder->bEnable == OMX_TRUE) {
3333 frm_int =0;
3334 time_stamp_dts.set_timestamp_reorder_mode(true);
3335 } else
3336 time_stamp_dts.set_timestamp_reorder_mode(false);
3337 } else {
3338 time_stamp_dts.set_timestamp_reorder_mode(false);
3339 if (reorder->bEnable == OMX_TRUE) {
3340 eRet = OMX_ErrorUnsupportedSetting;
3341 }
3342 }
3343 }
3344 break;
3345 case OMX_IndexParamVideoProfileLevelCurrent: {
3346 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3347 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3348 if (pParam) {
3349 m_profile_lvl.eProfile = pParam->eProfile;
3350 m_profile_lvl.eLevel = pParam->eLevel;
3351 }
3352 break;
Arun Menon888aa852013-05-30 11:24:42 -07003353
Arun Menon906de572013-06-18 17:01:40 -07003354 }
Arun Menone5652482013-08-04 13:33:05 -07003355 case OMX_QcomIndexParamVideoMetaBufferMode:
3356 {
3357 StoreMetaDataInBuffersParams *metabuffer =
3358 (StoreMetaDataInBuffersParams *)paramData;
3359 if (!metabuffer) {
3360 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3361 eRet = OMX_ErrorBadParameter;
3362 break;
3363 }
3364 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3365 //set property dynamic buffer mode to driver.
3366 struct v4l2_control control;
3367 struct v4l2_format fmt;
3368 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3369 if (metabuffer->bStoreMetaData == true) {
3370 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3371 } else {
3372 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3373 }
3374 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3375 if (!rc) {
3376 DEBUG_PRINT_HIGH(" %s buffer mode\n",
3377 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
3378 } else {
3379 DEBUG_PRINT_ERROR("Failed to %s buffer mode\n",
3380 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3381 eRet = OMX_ErrorUnsupportedSetting;
3382 }
3383 } else {
3384 DEBUG_PRINT_ERROR(
3385 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %d\n",
3386 metabuffer->nPortIndex);
3387 eRet = OMX_ErrorUnsupportedSetting;
3388 }
3389 break;
3390 }
Arun Menon906de572013-06-18 17:01:40 -07003391 default: {
3392 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3393 eRet = OMX_ErrorUnsupportedIndex;
3394 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003395 }
Arun Menon906de572013-06-18 17:01:40 -07003396 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003397}
3398
3399/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003400 FUNCTION
3401 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003402
Arun Menon906de572013-06-18 17:01:40 -07003403 DESCRIPTION
3404 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003405
Arun Menon906de572013-06-18 17:01:40 -07003406 PARAMETERS
3407 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003408
Arun Menon906de572013-06-18 17:01:40 -07003409 RETURN VALUE
3410 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003411
Arun Menon906de572013-06-18 17:01:40 -07003412 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003413OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003414 OMX_IN OMX_INDEXTYPE configIndex,
3415 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003416{
Arun Menon906de572013-06-18 17:01:40 -07003417 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003418
Arun Menon906de572013-06-18 17:01:40 -07003419 if (m_state == OMX_StateInvalid) {
3420 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003421 return OMX_ErrorInvalidState;
3422 }
Arun Menon906de572013-06-18 17:01:40 -07003423
3424 switch ((unsigned long)configIndex) {
3425 case OMX_QcomIndexConfigInterlaced: {
3426 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3427 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3428 if (configFmt->nPortIndex == 1) {
3429 if (configFmt->nIndex == 0) {
3430 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3431 } else if (configFmt->nIndex == 1) {
3432 configFmt->eInterlaceType =
3433 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3434 } else if (configFmt->nIndex == 2) {
3435 configFmt->eInterlaceType =
3436 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3437 } else {
3438 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3439 " NoMore Interlaced formats\n");
3440 eRet = OMX_ErrorNoMore;
3441 }
3442
3443 } else {
3444 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3445 (int)configFmt->nPortIndex);
3446 eRet = OMX_ErrorBadPortIndex;
3447 }
3448 break;
3449 }
3450 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3451 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3452 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3453 decoderinstances->nNumOfInstances = 16;
3454 /*TODO: How to handle this case */
3455 break;
3456 }
3457 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3458 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3459 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3460 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3461 h264_parser->get_frame_pack_data(configFmt);
3462 } else {
3463 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3464 }
3465 break;
3466 }
3467 case OMX_IndexConfigCommonOutputCrop: {
3468 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3469 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3470 break;
3471 }
3472 default: {
3473 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3474 eRet = OMX_ErrorBadParameter;
3475 }
3476
Shalaj Jain273b3e02012-06-22 19:08:03 -07003477 }
Arun Menon906de572013-06-18 17:01:40 -07003478
3479 return eRet;
3480}
3481
3482/* ======================================================================
3483 FUNCTION
3484 omx_vdec::SetConfig
3485
3486 DESCRIPTION
3487 OMX Set Config method implementation
3488
3489 PARAMETERS
3490 <TBD>.
3491
3492 RETURN VALUE
3493 OMX Error None if successful.
3494 ========================================================================== */
3495OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3496 OMX_IN OMX_INDEXTYPE configIndex,
3497 OMX_IN OMX_PTR configData)
3498{
3499 if (m_state == OMX_StateInvalid) {
3500 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3501 return OMX_ErrorInvalidState;
3502 }
3503
3504 OMX_ERRORTYPE ret = OMX_ErrorNone;
3505 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3506
3507 DEBUG_PRINT_LOW("\n Set Config Called");
3508
3509 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3510 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3511 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3512 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
3513 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3514 OMX_U32 extra_size;
3515 // Parsing done here for the AVC atom is definitely not generic
3516 // Currently this piece of code is working, but certainly
3517 // not tested with all .mp4 files.
3518 // Incase of failure, we might need to revisit this
3519 // for a generic piece of code.
3520
3521 // Retrieve size of NAL length field
3522 // byte #4 contains the size of NAL lenght field
3523 nal_length = (config->pData[4] & 0x03) + 1;
3524
3525 extra_size = 0;
3526 if (nal_length > 2) {
3527 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3528 extra_size = (nal_length - 2) * 2;
3529 }
3530
3531 // SPS starts from byte #6
3532 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3533 OMX_U8 *pDestBuf;
3534 m_vendor_config.nPortIndex = config->nPortIndex;
3535
3536 // minus 6 --> SPS starts from byte #6
3537 // minus 1 --> picture param set byte to be ignored from avcatom
3538 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3539 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3540 OMX_U32 len;
3541 OMX_U8 index = 0;
3542 // case where SPS+PPS is sent as part of set_config
3543 pDestBuf = m_vendor_config.pData;
3544
3545 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
3546 m_vendor_config.nPortIndex,
3547 m_vendor_config.nDataSize,
3548 m_vendor_config.pData);
3549 while (index < 2) {
3550 uint8 *psize;
3551 len = *pSrcBuf;
3552 len = len << 8;
3553 len |= *(pSrcBuf + 1);
3554 psize = (uint8 *) & len;
3555 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3556 for (unsigned int i = 0; i < nal_length; i++) {
3557 pDestBuf[i] = psize[nal_length - 1 - i];
3558 }
3559 //memcpy(pDestBuf,pSrcBuf,(len+2));
3560 pDestBuf += len + nal_length;
3561 pSrcBuf += len + 2;
3562 index++;
3563 pSrcBuf++; // skip picture param set
3564 len = 0;
3565 }
3566 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3567 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3568 m_vendor_config.nPortIndex = config->nPortIndex;
3569 m_vendor_config.nDataSize = config->nDataSize;
3570 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3571 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3572 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3573 if (m_vendor_config.pData) {
3574 free(m_vendor_config.pData);
3575 m_vendor_config.pData = NULL;
3576 m_vendor_config.nDataSize = 0;
3577 }
3578
3579 if (((*((OMX_U32 *) config->pData)) &
3580 VC1_SP_MP_START_CODE_MASK) ==
3581 VC1_SP_MP_START_CODE) {
3582 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3583 m_vendor_config.nPortIndex = config->nPortIndex;
3584 m_vendor_config.nDataSize = config->nDataSize;
3585 m_vendor_config.pData =
3586 (OMX_U8 *) malloc(config->nDataSize);
3587 memcpy(m_vendor_config.pData, config->pData,
3588 config->nDataSize);
3589 m_vc1_profile = VC1_SP_MP_RCV;
3590 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
3591 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3592 m_vendor_config.nPortIndex = config->nPortIndex;
3593 m_vendor_config.nDataSize = config->nDataSize;
3594 m_vendor_config.pData =
3595 (OMX_U8 *) malloc((config->nDataSize));
3596 memcpy(m_vendor_config.pData, config->pData,
3597 config->nDataSize);
3598 m_vc1_profile = VC1_AP;
3599 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
3600 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3601 m_vendor_config.nPortIndex = config->nPortIndex;
3602 m_vendor_config.nDataSize = config->nDataSize;
3603 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3604 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3605 m_vc1_profile = VC1_SP_MP_RCV;
3606 } else {
3607 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3608 }
3609 }
3610 return ret;
3611 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3612 struct v4l2_control temp;
3613 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3614
3615 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3616 switch (pNal->nNaluBytes) {
3617 case 0:
3618 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3619 break;
3620 case 2:
3621 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3622 break;
3623 case 4:
3624 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3625 break;
3626 default:
3627 return OMX_ErrorUnsupportedSetting;
3628 }
3629
3630 if (!arbitrary_bytes) {
3631 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3632 * with start code, so only need to notify driver in frame by frame mode */
3633 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3634 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3635 return OMX_ErrorHardware;
3636 }
3637 }
3638
3639 nal_length = pNal->nNaluBytes;
3640 m_frame_parser.init_nal_length(nal_length);
3641
3642 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
3643 return ret;
3644 } else if (configIndex == OMX_IndexVendorVideoFrameRate) {
3645 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
3646 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps);
3647
3648 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3649 if (config->bEnabled) {
3650 if ((config->nFps >> 16) > 0) {
3651 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d",
3652 config->nFps >> 16);
3653 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3654 drv_ctx.frame_rate.fps_denominator);
3655
3656 if (!drv_ctx.frame_rate.fps_numerator) {
3657 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3658 drv_ctx.frame_rate.fps_numerator = 30;
3659 }
3660
3661 if (drv_ctx.frame_rate.fps_denominator) {
3662 drv_ctx.frame_rate.fps_numerator = (int)
3663 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3664 }
3665
3666 drv_ctx.frame_rate.fps_denominator = 1;
3667 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3668 drv_ctx.frame_rate.fps_numerator;
3669
3670 struct v4l2_outputparm oparm;
3671 /*XXX: we're providing timing info as seconds per frame rather than frames
3672 * per second.*/
3673 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3674 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3675
3676 struct v4l2_streamparm sparm;
3677 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3678 sparm.parm.output = oparm;
3679 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3680 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3681 performance might be affected");
3682 ret = OMX_ErrorHardware;
3683 }
3684 client_set_fps = true;
3685 } else {
3686 DEBUG_PRINT_ERROR("Frame rate not supported.");
3687 ret = OMX_ErrorUnsupportedSetting;
3688 }
3689 } else {
3690 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3691 client_set_fps = false;
3692 }
3693 } else {
3694 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3695 (int)config->nPortIndex);
3696 ret = OMX_ErrorBadPortIndex;
3697 }
3698
3699 return ret;
3700 }
3701
3702 return OMX_ErrorNotImplemented;
3703}
3704
3705/* ======================================================================
3706 FUNCTION
3707 omx_vdec::GetExtensionIndex
3708
3709 DESCRIPTION
3710 OMX GetExtensionIndex method implementaion. <TBD>
3711
3712 PARAMETERS
3713 <TBD>.
3714
3715 RETURN VALUE
3716 OMX Error None if everything successful.
3717
3718 ========================================================================== */
3719OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3720 OMX_IN OMX_STRING paramName,
3721 OMX_OUT OMX_INDEXTYPE* indexType)
3722{
3723 if (m_state == OMX_StateInvalid) {
3724 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3725 return OMX_ErrorInvalidState;
3726 } else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3727 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3728 } else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003729 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3730 }
3731#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003732 else if (!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003733 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Arun Menon906de572013-06-18 17:01:40 -07003734 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003735 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Arun Menon906de572013-06-18 17:01:40 -07003736 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003737 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3738 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Arun Menon906de572013-06-18 17:01:40 -07003739 } else if (!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003740 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3741 }
3742#endif
Arun Menone5652482013-08-04 13:33:05 -07003743 else if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers", sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) {
3744 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
3745 }
Arun Menon906de572013-06-18 17:01:40 -07003746 else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003747 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3748 return OMX_ErrorNotImplemented;
3749 }
3750 return OMX_ErrorNone;
3751}
3752
3753/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003754 FUNCTION
3755 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07003756
Arun Menon906de572013-06-18 17:01:40 -07003757 DESCRIPTION
3758 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003759
Arun Menon906de572013-06-18 17:01:40 -07003760 PARAMETERS
3761 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003762
Arun Menon906de572013-06-18 17:01:40 -07003763 RETURN VALUE
3764 Error None if everything is successful.
3765 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003766OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003767 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003768{
Arun Menon906de572013-06-18 17:01:40 -07003769 *state = m_state;
3770 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
3771 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003772}
3773
3774/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003775 FUNCTION
3776 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07003777
Arun Menon906de572013-06-18 17:01:40 -07003778 DESCRIPTION
3779 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003780
Arun Menon906de572013-06-18 17:01:40 -07003781 PARAMETERS
3782 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003783
Arun Menon906de572013-06-18 17:01:40 -07003784 RETURN VALUE
3785 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003786
Arun Menon906de572013-06-18 17:01:40 -07003787 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003788OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003789 OMX_IN OMX_U32 port,
3790 OMX_IN OMX_HANDLETYPE peerComponent,
3791 OMX_IN OMX_U32 peerPort,
3792 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003793{
Arun Menon906de572013-06-18 17:01:40 -07003794 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3795 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003796}
3797
3798/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003799 FUNCTION
3800 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07003801
Arun Menon906de572013-06-18 17:01:40 -07003802 DESCRIPTION
3803 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07003804
Arun Menon906de572013-06-18 17:01:40 -07003805 PARAMETERS
3806 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003807
Arun Menon906de572013-06-18 17:01:40 -07003808 RETURN VALUE
3809 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07003810
Arun Menon906de572013-06-18 17:01:40 -07003811 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003812OMX_ERRORTYPE omx_vdec::allocate_extradata()
3813{
3814#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003815 if (drv_ctx.extradata_info.buffer_size) {
3816 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
3817 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3818 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3819 free_ion_memory(&drv_ctx.extradata_info.ion);
3820 }
3821 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
3822 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
3823 drv_ctx.extradata_info.size, 4096,
3824 &drv_ctx.extradata_info.ion.ion_alloc_data,
3825 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
3826 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
3827 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
3828 return OMX_ErrorInsufficientResources;
3829 }
3830 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
3831 drv_ctx.extradata_info.size,
3832 PROT_READ|PROT_WRITE, MAP_SHARED,
3833 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
3834 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
3835 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
3836 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3837 free_ion_memory(&drv_ctx.extradata_info.ion);
3838 return OMX_ErrorInsufficientResources;
3839 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003840 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003841#endif
Arun Menon906de572013-06-18 17:01:40 -07003842 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003843}
3844
Arun Menon906de572013-06-18 17:01:40 -07003845void omx_vdec::free_extradata()
3846{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003847#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003848 if (drv_ctx.extradata_info.uaddr) {
3849 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3850 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3851 free_ion_memory(&drv_ctx.extradata_info.ion);
3852 }
3853 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003854#endif
3855}
3856
Shalaj Jain273b3e02012-06-22 19:08:03 -07003857OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07003858 OMX_IN OMX_HANDLETYPE hComp,
3859 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3860 OMX_IN OMX_U32 port,
3861 OMX_IN OMX_PTR appData,
3862 OMX_IN OMX_U32 bytes,
3863 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003864{
Arun Menon906de572013-06-18 17:01:40 -07003865 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3866 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
3867 unsigned i= 0; // Temporary counter
3868 struct vdec_setbuffer_cmd setbuffers;
3869 OMX_PTR privateAppData = NULL;
3870 private_handle_t *handle = NULL;
3871 OMX_U8 *buff = buffer;
3872 struct v4l2_buffer buf;
3873 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3874 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003875
Arun Menon906de572013-06-18 17:01:40 -07003876 if (!m_out_mem_ptr) {
3877 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
3878 eRet = allocate_output_headers();
3879 if (eRet == OMX_ErrorNone)
3880 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07003881 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003882
Arun Menon906de572013-06-18 17:01:40 -07003883 if (eRet == OMX_ErrorNone) {
3884 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
3885 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
3886 break;
3887 }
3888 }
3889 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003890
Arun Menon906de572013-06-18 17:01:40 -07003891 if (i >= drv_ctx.op_buf.actualcount) {
3892 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
3893 eRet = OMX_ErrorInsufficientResources;
3894 }
3895
3896 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003897#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003898 if (m_enable_android_native_buffers) {
3899 if (m_use_android_native_buffers) {
3900 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
3901 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3902 handle = (private_handle_t *)nBuf->handle;
3903 privateAppData = params->pAppPrivate;
3904 } else {
3905 handle = (private_handle_t *)buff;
3906 privateAppData = appData;
3907 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003908
Arun Menon906de572013-06-18 17:01:40 -07003909 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
3910 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
3911 " expected %u, got %lu",
3912 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
3913 return OMX_ErrorBadParameter;
3914 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003915
Arun Menon906de572013-06-18 17:01:40 -07003916 if (!m_use_android_native_buffers) {
3917 if (!secure_mode) {
3918 buff = (OMX_U8*)mmap(0, handle->size,
3919 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3920 if (buff == MAP_FAILED) {
3921 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3922 return OMX_ErrorInsufficientResources;
3923 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003924 }
3925 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003926#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003927 native_buffer[i].nativehandle = handle;
3928 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003929#endif
Arun Menon906de572013-06-18 17:01:40 -07003930 if (!handle) {
3931 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
3932 return OMX_ErrorBadParameter;
3933 }
3934 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
3935 drv_ctx.ptr_outputbuffer[i].offset = 0;
3936 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
3937 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
3938 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
3939 } else
3940#endif
3941
3942 if (!ouput_egl_buffers && !m_use_output_pmem) {
3943#ifdef USE_ION
3944 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
3945 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
3946 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
3947 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
3948 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
3949 DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd);
3950 return OMX_ErrorInsufficientResources;
3951 }
3952 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3953 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
3954#else
3955 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3956 open (MEM_DEVICE,O_RDWR);
3957
3958 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
3959 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
3960 return OMX_ErrorInsufficientResources;
3961 }
3962
3963 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
3964 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
3965 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3966 open (MEM_DEVICE,O_RDWR);
3967 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
3968 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
3969 return OMX_ErrorInsufficientResources;
3970 }
3971 }
3972
3973 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
3974 drv_ctx.op_buf.buffer_size,
3975 drv_ctx.op_buf.alignment)) {
3976 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3977 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
3978 return OMX_ErrorInsufficientResources;
3979 }
3980#endif
3981 if (!secure_mode) {
3982 drv_ctx.ptr_outputbuffer[i].bufferaddr =
3983 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
3984 PROT_READ|PROT_WRITE, MAP_SHARED,
3985 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
3986 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
3987 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
3988#ifdef USE_ION
3989 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
3990#endif
3991 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
3992 return OMX_ErrorInsufficientResources;
3993 }
3994 }
3995 drv_ctx.ptr_outputbuffer[i].offset = 0;
3996 privateAppData = appData;
3997 } else {
3998
3999 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4000 if (!appData || !bytes ) {
4001 if (!secure_mode && !buffer) {
4002 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4003 return OMX_ErrorBadParameter;
4004 }
4005 }
4006
4007 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4008 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4009 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4010 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4011 !pmem_list->nEntries ||
4012 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4013 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4014 return OMX_ErrorBadParameter;
4015 }
4016 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4017 pmem_list->entryList->entry;
4018 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4019 pmem_info->pmem_fd);
4020 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4021 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4022 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4023 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4024 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4025 privateAppData = appData;
4026 }
4027 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4028 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4029
4030 *bufferHdr = (m_out_mem_ptr + i );
4031 if (secure_mode)
4032 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4033 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4034 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4035 sizeof (vdec_bufferpayload));
4036
4037 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4038 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4039 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4040
4041 buf.index = i;
4042 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4043 buf.memory = V4L2_MEMORY_USERPTR;
4044 plane[0].length = drv_ctx.op_buf.buffer_size;
4045 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4046 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4047 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4048 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4049 plane[0].data_offset = 0;
4050 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4051 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4052 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4053 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4054#ifdef USE_ION
4055 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4056#endif
4057 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4058 plane[extra_idx].data_offset = 0;
4059 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4060 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004061 return OMX_ErrorBadParameter;
4062 }
Arun Menon906de572013-06-18 17:01:40 -07004063 buf.m.planes = plane;
4064 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004065
Arun Menon906de572013-06-18 17:01:40 -07004066 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4067 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4068 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004069 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004070 }
4071
Arun Menon906de572013-06-18 17:01:40 -07004072 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4073 enum v4l2_buf_type buf_type;
4074 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4075 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4076 return OMX_ErrorInsufficientResources;
4077 } else {
4078 streaming[CAPTURE_PORT] = true;
4079 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004080 }
4081 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004082
Arun Menon906de572013-06-18 17:01:40 -07004083 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4084 if (m_enable_android_native_buffers) {
4085 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4086 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4087 } else {
4088 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004089 }
Arun Menon906de572013-06-18 17:01:40 -07004090 (*bufferHdr)->pAppPrivate = privateAppData;
4091 BITMASK_SET(&m_out_bm_count,i);
4092 }
4093 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004094}
4095
4096/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004097 FUNCTION
4098 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004099
Arun Menon906de572013-06-18 17:01:40 -07004100 DESCRIPTION
4101 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004102
Arun Menon906de572013-06-18 17:01:40 -07004103 PARAMETERS
4104 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004105
Arun Menon906de572013-06-18 17:01:40 -07004106 RETURN VALUE
4107 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004108
Arun Menon906de572013-06-18 17:01:40 -07004109 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004110OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004111 OMX_IN OMX_HANDLETYPE hComp,
4112 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4113 OMX_IN OMX_U32 port,
4114 OMX_IN OMX_PTR appData,
4115 OMX_IN OMX_U32 bytes,
4116 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004117{
Arun Menon906de572013-06-18 17:01:40 -07004118 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4119 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4120 if (!m_inp_heap_ptr)
4121 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4122 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4123 drv_ctx.ip_buf.actualcount);
4124 if (!m_phdr_pmem_ptr)
4125 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4126 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4127 drv_ctx.ip_buf.actualcount);
4128 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4129 DEBUG_PRINT_ERROR("Insufficent memory");
4130 eRet = OMX_ErrorInsufficientResources;
4131 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4132 input_use_buffer = true;
4133 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4134 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4135 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4136 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4137 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4138 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4139 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4140 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4141 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
4142 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4143 (unsigned)NULL, (unsigned)NULL)) {
4144 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4145 return OMX_ErrorInsufficientResources;
4146 }
4147 m_in_alloc_cnt++;
4148 } else {
4149 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4150 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004151 }
Arun Menon906de572013-06-18 17:01:40 -07004152 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004153}
4154
4155/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004156 FUNCTION
4157 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004158
Arun Menon906de572013-06-18 17:01:40 -07004159 DESCRIPTION
4160 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004161
Arun Menon906de572013-06-18 17:01:40 -07004162 PARAMETERS
4163 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004164
Arun Menon906de572013-06-18 17:01:40 -07004165 RETURN VALUE
4166 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004167
Arun Menon906de572013-06-18 17:01:40 -07004168 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004169OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004170 OMX_IN OMX_HANDLETYPE hComp,
4171 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4172 OMX_IN OMX_U32 port,
4173 OMX_IN OMX_PTR appData,
4174 OMX_IN OMX_U32 bytes,
4175 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004176{
Arun Menon906de572013-06-18 17:01:40 -07004177 OMX_ERRORTYPE error = OMX_ErrorNone;
4178 struct vdec_setbuffer_cmd setbuffers;
4179
4180 if (bufferHdr == NULL || bytes == 0) {
4181 if (!secure_mode && buffer == NULL) {
4182 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4183 return OMX_ErrorBadParameter;
4184 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004185 }
Arun Menon906de572013-06-18 17:01:40 -07004186 if (m_state == OMX_StateInvalid) {
4187 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4188 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004189 }
Arun Menon906de572013-06-18 17:01:40 -07004190 if (port == OMX_CORE_INPUT_PORT_INDEX)
4191 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4192 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4193 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4194 else {
4195 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4196 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004197 }
Arun Menon906de572013-06-18 17:01:40 -07004198 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4199 if (error == OMX_ErrorNone) {
4200 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4201 // Send the callback now
4202 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4203 post_event(OMX_CommandStateSet,OMX_StateIdle,
4204 OMX_COMPONENT_GENERATE_EVENT);
4205 }
4206 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4207 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4208 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4209 post_event(OMX_CommandPortEnable,
4210 OMX_CORE_INPUT_PORT_INDEX,
4211 OMX_COMPONENT_GENERATE_EVENT);
4212 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4213 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4214 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4215 post_event(OMX_CommandPortEnable,
4216 OMX_CORE_OUTPUT_PORT_INDEX,
4217 OMX_COMPONENT_GENERATE_EVENT);
4218 }
4219 }
4220 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004221}
4222
4223OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004224 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004225{
Arun Menon906de572013-06-18 17:01:40 -07004226 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4227 if (m_inp_heap_ptr[bufferindex].pBuffer)
4228 free(m_inp_heap_ptr[bufferindex].pBuffer);
4229 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4230 }
4231 if (pmem_bufferHdr)
4232 free_input_buffer(pmem_bufferHdr);
4233 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004234}
4235
4236OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4237{
Arun Menon906de572013-06-18 17:01:40 -07004238 unsigned int index = 0;
4239 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4240 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004241 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004242
Arun Menon906de572013-06-18 17:01:40 -07004243 index = bufferHdr - m_inp_mem_ptr;
4244 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4245
4246 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
4247 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4248 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4249 struct vdec_setbuffer_cmd setbuffers;
4250 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4251 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4252 sizeof (vdec_bufferpayload));
4253 if (!secure_mode) {
4254 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4255 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4256 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4257 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4258 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4259 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4260 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4261 }
4262 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4263 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4264 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4265 free(m_desc_buffer_ptr[index].buf_addr);
4266 m_desc_buffer_ptr[index].buf_addr = NULL;
4267 m_desc_buffer_ptr[index].desc_data_size = 0;
4268 }
4269#ifdef USE_ION
4270 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4271#endif
4272 }
4273 }
4274
4275 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004276}
4277
4278OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4279{
Arun Menon906de572013-06-18 17:01:40 -07004280 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004281
Arun Menon906de572013-06-18 17:01:40 -07004282 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4283 return OMX_ErrorBadParameter;
4284 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004285
Arun Menon906de572013-06-18 17:01:40 -07004286 index = bufferHdr - m_out_mem_ptr;
4287 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004288
Arun Menon906de572013-06-18 17:01:40 -07004289 if (index < drv_ctx.op_buf.actualcount
4290 && drv_ctx.ptr_outputbuffer) {
4291 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
4292 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004293
Arun Menon906de572013-06-18 17:01:40 -07004294 struct vdec_setbuffer_cmd setbuffers;
4295 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4296 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4297 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004298#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004299 if (m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004300 if (!secure_mode) {
Arun Menon906de572013-06-18 17:01:40 -07004301 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4302 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4303 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4304 }
Praveen Chavan212671f2013-04-05 20:00:42 -07004305 }
Arun Menon906de572013-06-18 17:01:40 -07004306 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4307 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004308#endif
Arun Menon906de572013-06-18 17:01:40 -07004309 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4310 if (!secure_mode) {
4311 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4312 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4313 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4314 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4315 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4316 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4317 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4318 }
4319 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4320 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004321#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004322 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004323#endif
Arun Menon906de572013-06-18 17:01:40 -07004324 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004325#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004326 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004327#endif
Arun Menon906de572013-06-18 17:01:40 -07004328 if (release_output_done()) {
4329 free_extradata();
4330 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004331 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004332
Arun Menon906de572013-06-18 17:01:40 -07004333 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004334
4335}
4336
4337OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004338 OMX_BUFFERHEADERTYPE **bufferHdr,
4339 OMX_U32 port,
4340 OMX_PTR appData,
4341 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004342{
Arun Menon906de572013-06-18 17:01:40 -07004343 OMX_BUFFERHEADERTYPE *input = NULL;
4344 unsigned char *buf_addr = NULL;
4345 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4346 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004347
Arun Menon906de572013-06-18 17:01:40 -07004348 /* Sanity Check*/
4349 if (bufferHdr == NULL) {
4350 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004351 }
4352
Arun Menon906de572013-06-18 17:01:40 -07004353 if (m_inp_heap_ptr == NULL) {
4354 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4355 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4356 drv_ctx.ip_buf.actualcount);
4357 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4358 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4359 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004360
Arun Menon906de572013-06-18 17:01:40 -07004361 if (m_inp_heap_ptr == NULL) {
4362 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4363 return OMX_ErrorInsufficientResources;
4364 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004365 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004366
Arun Menon906de572013-06-18 17:01:40 -07004367 /*Find a Free index*/
4368 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4369 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
4370 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4371 break;
4372 }
4373 }
4374
4375 if (i < drv_ctx.ip_buf.actualcount) {
4376 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4377
4378 if (buf_addr == NULL) {
4379 return OMX_ErrorInsufficientResources;
4380 }
4381
4382 *bufferHdr = (m_inp_heap_ptr + i);
4383 input = *bufferHdr;
4384 BITMASK_SET(&m_heap_inp_bm_count,i);
4385
4386 input->pBuffer = (OMX_U8 *)buf_addr;
4387 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4388 input->nVersion.nVersion = OMX_SPEC_VERSION;
4389 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4390 input->pAppPrivate = appData;
4391 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4392 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4393 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4394 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
4395 /*Add the Buffers to freeq*/
4396 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4397 (unsigned)NULL, (unsigned)NULL)) {
4398 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4399 return OMX_ErrorInsufficientResources;
4400 }
4401 } else {
4402 return OMX_ErrorBadParameter;
4403 }
4404
4405 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004406
4407}
4408
4409
4410/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004411 FUNCTION
4412 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004413
Arun Menon906de572013-06-18 17:01:40 -07004414 DESCRIPTION
4415 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004416
Arun Menon906de572013-06-18 17:01:40 -07004417 PARAMETERS
4418 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004419
Arun Menon906de572013-06-18 17:01:40 -07004420 RETURN VALUE
4421 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004422
Arun Menon906de572013-06-18 17:01:40 -07004423 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004424OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004425 OMX_IN OMX_HANDLETYPE hComp,
4426 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4427 OMX_IN OMX_U32 port,
4428 OMX_IN OMX_PTR appData,
4429 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004430{
4431
Arun Menon906de572013-06-18 17:01:40 -07004432 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4433 struct vdec_setbuffer_cmd setbuffers;
4434 OMX_BUFFERHEADERTYPE *input = NULL;
4435 unsigned i = 0;
4436 unsigned char *buf_addr = NULL;
4437 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004438
Arun Menon906de572013-06-18 17:01:40 -07004439 if (bytes != drv_ctx.ip_buf.buffer_size) {
4440 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
4441 bytes, drv_ctx.ip_buf.buffer_size);
4442 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004443 }
4444
Arun Menon906de572013-06-18 17:01:40 -07004445 if (!m_inp_mem_ptr) {
4446 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4447 drv_ctx.ip_buf.actualcount,
4448 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004449
Arun Menon906de572013-06-18 17:01:40 -07004450 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4451 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4452
4453 if (m_inp_mem_ptr == NULL) {
4454 return OMX_ErrorInsufficientResources;
4455 }
4456
4457 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4458 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4459
4460 if (drv_ctx.ptr_inputbuffer == NULL) {
4461 return OMX_ErrorInsufficientResources;
4462 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004463#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004464 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4465 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004466
Arun Menon906de572013-06-18 17:01:40 -07004467 if (drv_ctx.ip_buf_ion_info == NULL) {
4468 return OMX_ErrorInsufficientResources;
4469 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004470#endif
4471
Arun Menon906de572013-06-18 17:01:40 -07004472 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4473 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004474#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004475 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004476#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004477 }
4478 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004479
Arun Menon906de572013-06-18 17:01:40 -07004480 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4481 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4482 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4483 break;
4484 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004485 }
Arun Menon906de572013-06-18 17:01:40 -07004486
4487 if (i < drv_ctx.ip_buf.actualcount) {
4488 struct v4l2_buffer buf;
4489 struct v4l2_plane plane;
4490 int rc;
4491 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4492#ifdef USE_ION
4493 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4494 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4495 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4496 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4497 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4498 return OMX_ErrorInsufficientResources;
4499 }
4500 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4501#else
4502 pmem_fd = open (MEM_DEVICE,O_RDWR);
4503
4504 if (pmem_fd < 0) {
4505 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4506 return OMX_ErrorInsufficientResources;
4507 }
4508
4509 if (pmem_fd == 0) {
4510 pmem_fd = open (MEM_DEVICE,O_RDWR);
4511
4512 if (pmem_fd < 0) {
4513 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4514 return OMX_ErrorInsufficientResources;
4515 }
4516 }
4517
4518 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4519 drv_ctx.ip_buf.alignment)) {
4520 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4521 close(pmem_fd);
4522 return OMX_ErrorInsufficientResources;
4523 }
4524#endif
4525 if (!secure_mode) {
4526 buf_addr = (unsigned char *)mmap(NULL,
4527 drv_ctx.ip_buf.buffer_size,
4528 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4529
4530 if (buf_addr == MAP_FAILED) {
4531 close(pmem_fd);
4532#ifdef USE_ION
4533 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4534#endif
4535 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4536 return OMX_ErrorInsufficientResources;
4537 }
4538 }
4539 *bufferHdr = (m_inp_mem_ptr + i);
4540 if (secure_mode)
4541 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4542 else
4543 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4544 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4545 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4546 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4547 drv_ctx.ptr_inputbuffer [i].offset = 0;
4548
4549
4550 buf.index = i;
4551 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4552 buf.memory = V4L2_MEMORY_USERPTR;
4553 plane.bytesused = 0;
4554 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4555 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4556 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4557 plane.reserved[1] = 0;
4558 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4559 buf.m.planes = &plane;
4560 buf.length = 1;
4561
4562 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4563 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4564
4565 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4566
4567 if (rc) {
4568 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4569 /*TODO: How to handle this case */
4570 return OMX_ErrorInsufficientResources;
4571 }
4572
4573 input = *bufferHdr;
4574 BITMASK_SET(&m_inp_bm_count,i);
4575 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4576 if (secure_mode)
4577 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4578 else
4579 input->pBuffer = (OMX_U8 *)buf_addr;
4580 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4581 input->nVersion.nVersion = OMX_SPEC_VERSION;
4582 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4583 input->pAppPrivate = appData;
4584 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4585 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4586
4587 if (drv_ctx.disable_dmx) {
4588 eRet = allocate_desc_buffer(i);
4589 }
4590 } else {
4591 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4592 eRet = OMX_ErrorInsufficientResources;
4593 }
4594 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004595}
4596
4597
4598/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004599 FUNCTION
4600 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004601
Arun Menon906de572013-06-18 17:01:40 -07004602 DESCRIPTION
4603 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004604
Arun Menon906de572013-06-18 17:01:40 -07004605 PARAMETERS
4606 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004607
Arun Menon906de572013-06-18 17:01:40 -07004608 RETURN VALUE
4609 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004610
Arun Menon906de572013-06-18 17:01:40 -07004611 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004612OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004613 OMX_IN OMX_HANDLETYPE hComp,
4614 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4615 OMX_IN OMX_U32 port,
4616 OMX_IN OMX_PTR appData,
4617 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004618{
Arun Menon906de572013-06-18 17:01:40 -07004619 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4620 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4621 unsigned i= 0; // Temporary counter
4622 struct vdec_setbuffer_cmd setbuffers;
4623 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004624#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004625 int ion_device_fd =-1;
4626 struct ion_allocation_data ion_alloc_data;
4627 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004628#endif
Arun Menon906de572013-06-18 17:01:40 -07004629 if (!m_out_mem_ptr) {
4630 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4631 drv_ctx.op_buf.actualcount,
4632 drv_ctx.op_buf.buffer_size);
4633 int nBufHdrSize = 0;
4634 int nPlatformEntrySize = 0;
4635 int nPlatformListSize = 0;
4636 int nPMEMInfoSize = 0;
4637 int pmem_fd = -1;
4638 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004639
Arun Menon906de572013-06-18 17:01:40 -07004640 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4641 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4642 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004643
Arun Menon906de572013-06-18 17:01:40 -07004644 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4645 drv_ctx.op_buf.actualcount);
4646 nBufHdrSize = drv_ctx.op_buf.actualcount *
4647 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004648
Arun Menon906de572013-06-18 17:01:40 -07004649 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4650 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4651 nPlatformListSize = drv_ctx.op_buf.actualcount *
4652 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4653 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4654 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004655
Arun Menon906de572013-06-18 17:01:40 -07004656 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4657 sizeof(OMX_BUFFERHEADERTYPE),
4658 nPMEMInfoSize,
4659 nPlatformListSize);
4660 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4661 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004662#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004663 ion_device_fd = alloc_map_ion_memory(
4664 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4665 drv_ctx.op_buf.alignment,
4666 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4667 if (ion_device_fd < 0) {
4668 return OMX_ErrorInsufficientResources;
4669 }
4670 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004671#else
Arun Menon906de572013-06-18 17:01:40 -07004672 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004673
Arun Menon906de572013-06-18 17:01:40 -07004674 if (pmem_fd < 0) {
4675 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4676 drv_ctx.op_buf.buffer_size);
4677 return OMX_ErrorInsufficientResources;
4678 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004679
Arun Menon906de572013-06-18 17:01:40 -07004680 if (pmem_fd == 0) {
4681 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004682
Arun Menon906de572013-06-18 17:01:40 -07004683 if (pmem_fd < 0) {
4684 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4685 drv_ctx.op_buf.buffer_size);
4686 return OMX_ErrorInsufficientResources;
4687 }
4688 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004689
Arun Menon906de572013-06-18 17:01:40 -07004690 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4691 drv_ctx.op_buf.actualcount,
4692 drv_ctx.op_buf.alignment)) {
4693 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4694 close(pmem_fd);
4695 return OMX_ErrorInsufficientResources;
4696 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004697#endif
Arun Menon906de572013-06-18 17:01:40 -07004698 if (!secure_mode) {
4699 pmem_baseaddress = (unsigned char *)mmap(NULL,
4700 (drv_ctx.op_buf.buffer_size *
4701 drv_ctx.op_buf.actualcount),
4702 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4703 if (pmem_baseaddress == MAP_FAILED) {
4704 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4705 drv_ctx.op_buf.buffer_size);
4706 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004707#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004708 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004709#endif
Arun Menon906de572013-06-18 17:01:40 -07004710 return OMX_ErrorInsufficientResources;
4711 }
4712 }
4713 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4714 // Alloc mem for platform specific info
4715 char *pPtr=NULL;
4716 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4717 nPMEMInfoSize,1);
4718 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4719 calloc (sizeof(struct vdec_bufferpayload),
4720 drv_ctx.op_buf.actualcount);
4721 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4722 calloc (sizeof (struct vdec_output_frameinfo),
4723 drv_ctx.op_buf.actualcount);
4724#ifdef USE_ION
4725 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4726 calloc (sizeof(struct vdec_ion),
4727 drv_ctx.op_buf.actualcount);
4728#endif
4729
4730 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4731 && drv_ctx.ptr_respbuffer) {
4732 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4733 (drv_ctx.op_buf.buffer_size *
4734 drv_ctx.op_buf.actualcount);
4735 bufHdr = m_out_mem_ptr;
4736 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4737 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4738 (((char *) m_platform_list) + nPlatformListSize);
4739 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4740 (((char *) m_platform_entry) + nPlatformEntrySize);
4741 pPlatformList = m_platform_list;
4742 pPlatformEntry = m_platform_entry;
4743 pPMEMInfo = m_pmem_info;
4744
4745 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
4746
4747 // Settting the entire storage nicely
4748 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
4749 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
4750 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4751 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4752 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4753 // Set the values when we determine the right HxW param
4754 bufHdr->nAllocLen = bytes;
4755 bufHdr->nFilledLen = 0;
4756 bufHdr->pAppPrivate = appData;
4757 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4758 // Platform specific PMEM Information
4759 // Initialize the Platform Entry
4760 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
4761 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4762 pPlatformEntry->entry = pPMEMInfo;
4763 // Initialize the Platform List
4764 pPlatformList->nEntries = 1;
4765 pPlatformList->entryList = pPlatformEntry;
4766 // Keep pBuffer NULL till vdec is opened
4767 bufHdr->pBuffer = NULL;
4768 bufHdr->nOffset = 0;
4769
4770 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4771 pPMEMInfo->pmem_fd = 0;
4772 bufHdr->pPlatformPrivate = pPlatformList;
4773
4774 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
4775 m_pmem_info[i].pmem_fd = pmem_fd;
4776#ifdef USE_ION
4777 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
4778 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
4779 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
4780#endif
4781
4782 /*Create a mapping between buffers*/
4783 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
4784 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
4785 &drv_ctx.ptr_outputbuffer[i];
4786 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
4787 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4788 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
4789
4790 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
4791 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
4792 drv_ctx.ptr_outputbuffer[i].bufferaddr);
4793 // Move the buffer and buffer header pointers
4794 bufHdr++;
4795 pPMEMInfo++;
4796 pPlatformEntry++;
4797 pPlatformList++;
4798 }
4799 } else {
4800 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
4801 m_out_mem_ptr, pPtr);
4802 if (m_out_mem_ptr) {
4803 free(m_out_mem_ptr);
4804 m_out_mem_ptr = NULL;
4805 }
4806 if (pPtr) {
4807 free(pPtr);
4808 pPtr = NULL;
4809 }
4810 if (drv_ctx.ptr_outputbuffer) {
4811 free(drv_ctx.ptr_outputbuffer);
4812 drv_ctx.ptr_outputbuffer = NULL;
4813 }
4814 if (drv_ctx.ptr_respbuffer) {
4815 free(drv_ctx.ptr_respbuffer);
4816 drv_ctx.ptr_respbuffer = NULL;
4817 }
4818#ifdef USE_ION
4819 if (drv_ctx.op_buf_ion_info) {
4820 DEBUG_PRINT_LOW("\n Free o/p ion context");
4821 free(drv_ctx.op_buf_ion_info);
4822 drv_ctx.op_buf_ion_info = NULL;
4823 }
4824#endif
4825 eRet = OMX_ErrorInsufficientResources;
4826 }
4827 if (eRet == OMX_ErrorNone)
4828 eRet = allocate_extradata();
4829 }
4830
4831 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4832 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4833 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
4834 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004835 }
4836 }
Arun Menon906de572013-06-18 17:01:40 -07004837
4838 if (eRet == OMX_ErrorNone) {
4839 if (i < drv_ctx.op_buf.actualcount) {
4840 struct v4l2_buffer buf;
4841 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4842 int rc;
4843 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4844
4845 drv_ctx.ptr_outputbuffer[i].buffer_len =
4846 drv_ctx.op_buf.buffer_size;
4847
4848 *bufferHdr = (m_out_mem_ptr + i );
4849 if (secure_mode) {
4850 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4851 }
4852 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
4853
4854 buf.index = i;
4855 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4856 buf.memory = V4L2_MEMORY_USERPTR;
4857 plane[0].length = drv_ctx.op_buf.buffer_size;
4858 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4859 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004860#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004861 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004862#endif
Arun Menon906de572013-06-18 17:01:40 -07004863 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4864 plane[0].data_offset = 0;
4865 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4866 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4867 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4868 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 -07004869#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004870 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004871#endif
Arun Menon906de572013-06-18 17:01:40 -07004872 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4873 plane[extra_idx].data_offset = 0;
4874 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4875 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
4876 return OMX_ErrorBadParameter;
4877 }
4878 buf.m.planes = plane;
4879 buf.length = drv_ctx.num_planes;
4880 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
4881 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4882 if (rc) {
4883 /*TODO: How to handle this case */
4884 return OMX_ErrorInsufficientResources;
4885 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004886
Arun Menon906de572013-06-18 17:01:40 -07004887 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
4888 enum v4l2_buf_type buf_type;
4889 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4890 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
4891 if (rc) {
4892 return OMX_ErrorInsufficientResources;
4893 } else {
4894 streaming[CAPTURE_PORT] = true;
4895 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4896 }
4897 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004898
Arun Menon906de572013-06-18 17:01:40 -07004899 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
4900 (*bufferHdr)->pAppPrivate = appData;
4901 BITMASK_SET(&m_out_bm_count,i);
4902 } else {
4903 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
4904 eRet = OMX_ErrorInsufficientResources;
4905 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004906 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004907
Arun Menon906de572013-06-18 17:01:40 -07004908 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004909}
4910
4911
4912// AllocateBuffer -- API Call
4913/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004914 FUNCTION
4915 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004916
Arun Menon906de572013-06-18 17:01:40 -07004917 DESCRIPTION
4918 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07004919
Arun Menon906de572013-06-18 17:01:40 -07004920 PARAMETERS
4921 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004922
Arun Menon906de572013-06-18 17:01:40 -07004923 RETURN VALUE
4924 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004925
Arun Menon906de572013-06-18 17:01:40 -07004926 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004927OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004928 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4929 OMX_IN OMX_U32 port,
4930 OMX_IN OMX_PTR appData,
4931 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004932{
4933 unsigned i = 0;
4934 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
4935
4936 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07004937 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004938 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
4939 return OMX_ErrorInvalidState;
4940 }
4941
Arun Menon906de572013-06-18 17:01:40 -07004942 if (port == OMX_CORE_INPUT_PORT_INDEX) {
4943 if (arbitrary_bytes) {
4944 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
4945 } else {
4946 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
4947 }
4948 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08004949 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
4950 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07004951 } else {
4952 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4953 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004954 }
4955 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07004956 if (eRet == OMX_ErrorNone) {
4957 if (allocate_done()) {
4958 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004959 // Send the callback now
4960 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4961 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07004962 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004963 }
4964 }
Arun Menon906de572013-06-18 17:01:40 -07004965 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
4966 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4967 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4968 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004969 OMX_CORE_INPUT_PORT_INDEX,
4970 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07004971 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004972 }
Arun Menon906de572013-06-18 17:01:40 -07004973 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
4974 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4975 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004976 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07004977 OMX_CORE_OUTPUT_PORT_INDEX,
4978 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004979 }
4980 }
4981 }
4982 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
4983 return eRet;
4984}
4985
4986// Free Buffer - API call
4987/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004988 FUNCTION
4989 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004990
Arun Menon906de572013-06-18 17:01:40 -07004991 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07004992
Arun Menon906de572013-06-18 17:01:40 -07004993 PARAMETERS
4994 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004995
Arun Menon906de572013-06-18 17:01:40 -07004996 RETURN VALUE
4997 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004998
Arun Menon906de572013-06-18 17:01:40 -07004999 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005000OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005001 OMX_IN OMX_U32 port,
5002 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005003{
5004 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5005 unsigned int nPortIndex;
5006 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5007
Arun Menon906de572013-06-18 17:01:40 -07005008 if (m_state == OMX_StateIdle &&
5009 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005010 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
Arun Menon906de572013-06-18 17:01:40 -07005011 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5012 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005013 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Arun Menon906de572013-06-18 17:01:40 -07005014 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5015 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5016 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5017 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Arun Menon9f098152013-05-08 13:53:54 -07005018 DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port);
Arun Menon906de572013-06-18 17:01:40 -07005019 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005020 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5021 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005022 OMX_ErrorPortUnpopulated,
5023 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005024
5025 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005026 } else if (m_state != OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005027 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5028 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005029 OMX_ErrorPortUnpopulated,
5030 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005031 }
5032
Arun Menon906de572013-06-18 17:01:40 -07005033 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5034 /*Check if arbitrary bytes*/
5035 if (!arbitrary_bytes && !input_use_buffer)
5036 nPortIndex = buffer - m_inp_mem_ptr;
5037 else
5038 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005039
5040 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005041 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5042 // Clear the bit associated with it.
5043 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5044 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5045 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005046
Arun Menon906de572013-06-18 17:01:40 -07005047 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5048 if (m_phdr_pmem_ptr)
5049 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5050 } else {
5051 if (arbitrary_bytes) {
5052 if (m_phdr_pmem_ptr)
5053 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5054 else
5055 free_input_buffer(nPortIndex,NULL);
5056 } else
5057 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005058 }
Arun Menon906de572013-06-18 17:01:40 -07005059 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305060 if(release_input_done())
5061 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005062 /*Free the Buffer Header*/
5063 if (release_input_done()) {
5064 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5065 free_input_buffer_header();
5066 }
5067 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005068 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5069 eRet = OMX_ErrorBadPortIndex;
5070 }
5071
Arun Menon906de572013-06-18 17:01:40 -07005072 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5073 && release_input_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005074 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5075 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5076 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005077 OMX_CORE_INPUT_PORT_INDEX,
5078 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005079 }
Arun Menon906de572013-06-18 17:01:40 -07005080 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005081 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005082 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005083 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005084 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5085 // Clear the bit associated with it.
5086 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5087 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005088 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005089
Surajit Podder12aefac2013-08-06 18:43:32 +05305090 if(release_output_done()) {
5091 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5092 }
Arun Menon906de572013-06-18 17:01:40 -07005093 if (release_output_done()) {
5094 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005095 }
Arun Menon906de572013-06-18 17:01:40 -07005096 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005097 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5098 eRet = OMX_ErrorBadPortIndex;
5099 }
Arun Menon906de572013-06-18 17:01:40 -07005100 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5101 && release_output_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005102 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5103
Arun Menon906de572013-06-18 17:01:40 -07005104 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5105 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005106#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005107 if (m_enable_android_native_buffers) {
5108 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5109 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5110 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005111#endif
5112
Arun Menon906de572013-06-18 17:01:40 -07005113 post_event(OMX_CommandPortDisable,
5114 OMX_CORE_OUTPUT_PORT_INDEX,
5115 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005116 }
Arun Menon906de572013-06-18 17:01:40 -07005117 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005118 eRet = OMX_ErrorBadPortIndex;
5119 }
Arun Menon906de572013-06-18 17:01:40 -07005120 if ((eRet == OMX_ErrorNone) &&
5121 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5122 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005123 // Send the callback now
5124 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5125 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005126 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005127 }
5128 }
5129 return eRet;
5130}
5131
5132
5133/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005134 FUNCTION
5135 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005136
Arun Menon906de572013-06-18 17:01:40 -07005137 DESCRIPTION
5138 This routine is used to push the encoded video frames to
5139 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005140
Arun Menon906de572013-06-18 17:01:40 -07005141 PARAMETERS
5142 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005143
Arun Menon906de572013-06-18 17:01:40 -07005144 RETURN VALUE
5145 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005146
Arun Menon906de572013-06-18 17:01:40 -07005147 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005148OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005149 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005150{
Arun Menon906de572013-06-18 17:01:40 -07005151 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5152 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005153
Arun Menon906de572013-06-18 17:01:40 -07005154 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5155 codec_config_flag = true;
5156 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5157 } else {
5158 codec_config_flag = false;
5159 }
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07005160
Arun Menon906de572013-06-18 17:01:40 -07005161 if (m_state == OMX_StateInvalid) {
5162 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5163 return OMX_ErrorInvalidState;
5164 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005165
Arun Menon906de572013-06-18 17:01:40 -07005166 if (buffer == NULL) {
5167 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5168 return OMX_ErrorBadParameter;
5169 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005170
Arun Menon906de572013-06-18 17:01:40 -07005171 if (!m_inp_bEnabled) {
5172 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5173 return OMX_ErrorIncorrectStateOperation;
5174 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005175
Arun Menon906de572013-06-18 17:01:40 -07005176 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
5177 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
5178 return OMX_ErrorBadPortIndex;
5179 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005180
5181#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005182 if (iDivXDrmDecrypt) {
5183 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5184 if (drmErr != OMX_ErrorNone) {
5185 // this error can be ignored
5186 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5187 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005188 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005189#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005190 if (perf_flag) {
5191 if (!latency) {
5192 dec_time.stop();
5193 latency = dec_time.processing_time_us();
5194 dec_time.start();
5195 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005196 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005197
Arun Menon906de572013-06-18 17:01:40 -07005198 if (arbitrary_bytes) {
5199 nBufferIndex = buffer - m_inp_heap_ptr;
5200 } else {
5201 if (input_use_buffer == true) {
5202 nBufferIndex = buffer - m_inp_heap_ptr;
5203 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5204 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5205 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5206 buffer = &m_inp_mem_ptr[nBufferIndex];
5207 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5208 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5209 } else {
5210 nBufferIndex = buffer - m_inp_mem_ptr;
5211 }
5212 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005213
Arun Menon906de572013-06-18 17:01:40 -07005214 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
5215 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5216 return OMX_ErrorBadParameter;
5217 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005218
Arun Menon906de572013-06-18 17:01:40 -07005219 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5220 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5221 if (arbitrary_bytes) {
5222 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005223 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005224 } else {
5225 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5226 set_frame_rate(buffer->nTimeStamp);
5227 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5228 }
5229 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005230}
5231
5232/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005233 FUNCTION
5234 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005235
Arun Menon906de572013-06-18 17:01:40 -07005236 DESCRIPTION
5237 This routine is used to push the encoded video frames to
5238 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005239
Arun Menon906de572013-06-18 17:01:40 -07005240 PARAMETERS
5241 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005242
Arun Menon906de572013-06-18 17:01:40 -07005243 RETURN VALUE
5244 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005245
Arun Menon906de572013-06-18 17:01:40 -07005246 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005247OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005248 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005249{
Arun Menon906de572013-06-18 17:01:40 -07005250 int push_cnt = 0,i=0;
5251 unsigned nPortIndex = 0;
5252 OMX_ERRORTYPE ret = OMX_ErrorNone;
5253 struct vdec_input_frameinfo frameinfo;
5254 struct vdec_bufferpayload *temp_buffer;
5255 struct vdec_seqheader seq_header;
5256 bool port_setting_changed = true;
5257 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005258
Arun Menon906de572013-06-18 17:01:40 -07005259 /*Should we generate a Aync error event*/
5260 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
5261 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5262 return OMX_ErrorBadParameter;
5263 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005264
Arun Menon906de572013-06-18 17:01:40 -07005265 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005266
Arun Menon906de572013-06-18 17:01:40 -07005267 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
5268 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5269 nPortIndex);
5270 return OMX_ErrorBadParameter;
5271 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005272
Arun Menon906de572013-06-18 17:01:40 -07005273 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005274
Arun Menon906de572013-06-18 17:01:40 -07005275 /* return zero length and not an EOS buffer */
5276 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5277 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
5278 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5279 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5280 OMX_COMPONENT_GENERATE_EBD);
5281 return OMX_ErrorNone;
5282 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005283
5284
Arun Menon906de572013-06-18 17:01:40 -07005285 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5286 mp4StreamType psBits;
5287 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5288 psBits.numBytes = buffer->nFilledLen;
5289 mp4_headerparser.parseHeader(&psBits);
5290 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5291 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5292 if (not_coded_vop) {
5293 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
5294 buffer->nFilledLen,frame_count);
5295 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
5296 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5297 not_coded_vop = false;
5298 buffer->nFilledLen = 0;
5299 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005300 }
5301 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005302
Arun Menon906de572013-06-18 17:01:40 -07005303 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005304
Arun Menon906de572013-06-18 17:01:40 -07005305 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005306
Arun Menon906de572013-06-18 17:01:40 -07005307 ) {
5308 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5309 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5310 OMX_COMPONENT_GENERATE_EBD);
5311 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005312 }
5313
Arun Menon906de572013-06-18 17:01:40 -07005314 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005315
Arun Menon906de572013-06-18 17:01:40 -07005316 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) {
5317 return OMX_ErrorBadParameter;
5318 }
5319 /* If its first frame, H264 codec and reject is true, then parse the nal
5320 and get the profile. Based on this, reject the clip playback */
5321 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5322 m_reject_avc_1080p_mp) {
5323 first_frame = 1;
5324 DEBUG_PRINT_ERROR("\nParse nal to get the profile");
5325 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5326 NALU_TYPE_SPS);
5327 m_profile = h264_parser->get_profile();
5328 ret = is_video_session_supported();
5329 if (ret) {
5330 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5331 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5332 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5333 m_state = OMX_StateInvalid;
5334 return OMX_ErrorNone;
5335 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005336 }
5337
Arun Menon906de572013-06-18 17:01:40 -07005338 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5339 /*for use buffer we need to memcpy the data*/
5340 temp_buffer->buffer_len = buffer->nFilledLen;
5341
5342 if (input_use_buffer) {
5343 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5344 if (arbitrary_bytes) {
5345 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5346 } else {
5347 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5348 buffer->nFilledLen);
5349 }
5350 } else {
5351 return OMX_ErrorBadParameter;
5352 }
5353
5354 }
5355
5356 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5357 frameinfo.client_data = (void *) buffer;
5358 frameinfo.datalen = temp_buffer->buffer_len;
5359 frameinfo.flags = 0;
5360 frameinfo.offset = buffer->nOffset;
5361 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5362 frameinfo.pmem_offset = temp_buffer->offset;
5363 frameinfo.timestamp = buffer->nTimeStamp;
5364 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5365 DEBUG_PRINT_LOW("ETB: dmx enabled");
5366 if (m_demux_entries == 0) {
5367 extract_demux_addr_offsets(buffer);
5368 }
5369
5370 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5371 handle_demux_data(buffer);
5372 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5373 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5374 } else {
5375 frameinfo.desc_addr = NULL;
5376 frameinfo.desc_size = 0;
5377 }
5378 if (!arbitrary_bytes) {
5379 frameinfo.flags |= buffer->nFlags;
5380 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005381
5382#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005383 if (m_debug_timestamp) {
5384 if (arbitrary_bytes) {
5385 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5386 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5387 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5388 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5389 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5390 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005391 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005392#endif
5393
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005394log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005395
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005396if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005397 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5398 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5399 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005400
Arun Menon906de572013-06-18 17:01:40 -07005401 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5402 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5403 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5404 h264_scratch.nFilledLen = 0;
5405 nal_count = 0;
5406 look_ahead_nal = false;
5407 frame_count = 0;
5408 if (m_frame_parser.mutils)
5409 m_frame_parser.mutils->initialize_frame_checking_environment();
5410 m_frame_parser.flush();
5411 h264_last_au_ts = LLONG_MAX;
5412 h264_last_au_flags = 0;
5413 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5414 m_demux_entries = 0;
5415 }
5416 struct v4l2_buffer buf;
5417 struct v4l2_plane plane;
5418 memset( (void *)&buf, 0, sizeof(buf));
5419 memset( (void *)&plane, 0, sizeof(plane));
5420 int rc;
5421 unsigned long print_count;
5422 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005423 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Arun Menon906de572013-06-18 17:01:40 -07005424 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
5425 }
5426 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5427 buf.index = nPortIndex;
5428 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5429 buf.memory = V4L2_MEMORY_USERPTR;
5430 plane.bytesused = temp_buffer->buffer_len;
5431 plane.length = drv_ctx.ip_buf.buffer_size;
5432 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5433 (unsigned long)temp_buffer->offset;
5434 plane.reserved[0] = temp_buffer->pmem_fd;
5435 plane.reserved[1] = temp_buffer->offset;
5436 plane.data_offset = 0;
5437 buf.m.planes = &plane;
5438 buf.length = 1;
5439 if (frameinfo.timestamp >= LLONG_MAX) {
5440 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5441 }
5442 //assumption is that timestamp is in milliseconds
5443 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5444 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5445 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5446 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005447
Arun Menon906de572013-06-18 17:01:40 -07005448 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5449 if (rc) {
5450 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5451 return OMX_ErrorHardware;
5452 }
5453 if (!streaming[OUTPUT_PORT]) {
5454 enum v4l2_buf_type buf_type;
5455 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005456
Arun Menon906de572013-06-18 17:01:40 -07005457 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005458 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
Arun Menon906de572013-06-18 17:01:40 -07005459 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5460 if (!ret) {
5461 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
5462 streaming[OUTPUT_PORT] = true;
5463 } else {
5464 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
5465 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5466 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5467 OMX_COMPONENT_GENERATE_EBD);
5468 return OMX_ErrorBadParameter;
5469 }
5470 }
5471 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5472 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5473 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005474
Arun Menon906de572013-06-18 17:01:40 -07005475 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005476}
5477
5478/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005479 FUNCTION
5480 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005481
Arun Menon906de572013-06-18 17:01:40 -07005482 DESCRIPTION
5483 IL client uses this method to release the frame buffer
5484 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005485
Arun Menon906de572013-06-18 17:01:40 -07005486 PARAMETERS
5487 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005488
Arun Menon906de572013-06-18 17:01:40 -07005489 RETURN VALUE
5490 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005491
Arun Menon906de572013-06-18 17:01:40 -07005492 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005493OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005494 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005495{
5496
Arun Menon906de572013-06-18 17:01:40 -07005497 if (m_state == OMX_StateInvalid) {
5498 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5499 return OMX_ErrorInvalidState;
5500 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005501
Arun Menon906de572013-06-18 17:01:40 -07005502 if (!m_out_bEnabled) {
5503 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5504 return OMX_ErrorIncorrectStateOperation;
5505 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005506
Arun Menon906de572013-06-18 17:01:40 -07005507 if (buffer == NULL ||
5508 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) {
5509 return OMX_ErrorBadParameter;
5510 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005511
Arun Menon906de572013-06-18 17:01:40 -07005512 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
5513 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
5514 return OMX_ErrorBadPortIndex;
5515 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005516
Arun Menon906de572013-06-18 17:01:40 -07005517 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5518 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5519 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005520}
5521/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005522 FUNCTION
5523 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005524
Arun Menon906de572013-06-18 17:01:40 -07005525 DESCRIPTION
5526 IL client uses this method to release the frame buffer
5527 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005528
Arun Menon906de572013-06-18 17:01:40 -07005529 PARAMETERS
5530 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005531
Arun Menon906de572013-06-18 17:01:40 -07005532 RETURN VALUE
5533 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005534
Arun Menon906de572013-06-18 17:01:40 -07005535 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005536OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005537 OMX_IN OMX_HANDLETYPE hComp,
5538 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005539{
Arun Menon906de572013-06-18 17:01:40 -07005540 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5541 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5542 unsigned nPortIndex = 0;
5543 struct vdec_fillbuffer_cmd fillbuffer;
5544 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5545 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005546
Arun Menon906de572013-06-18 17:01:40 -07005547 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005548
Arun Menon906de572013-06-18 17:01:40 -07005549 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5550 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005551
Arun Menon906de572013-06-18 17:01:40 -07005552 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5553 bufferAdd, bufferAdd->pBuffer);
5554 /*Return back the output buffer to client*/
5555 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
5556 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5557 buffer->nFilledLen = 0;
5558 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5559 return OMX_ErrorNone;
5560 }
5561 pending_output_buffers++;
5562 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5563 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5564 if (ptr_respbuffer) {
5565 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5566 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005567
Arun Menon906de572013-06-18 17:01:40 -07005568 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5569 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5570 buffer->nFilledLen = 0;
5571 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5572 pending_output_buffers--;
5573 return OMX_ErrorBadParameter;
5574 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005575
Arun Menon906de572013-06-18 17:01:40 -07005576 int rc = 0;
5577 struct v4l2_buffer buf;
5578 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5579 memset( (void *)&buf, 0, sizeof(buf));
5580 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5581 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005582
Arun Menon906de572013-06-18 17:01:40 -07005583 buf.index = nPortIndex;
5584 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5585 buf.memory = V4L2_MEMORY_USERPTR;
5586 plane[0].bytesused = buffer->nFilledLen;
5587 plane[0].length = drv_ctx.op_buf.buffer_size;
5588 plane[0].m.userptr =
5589 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5590 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5591 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5592 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5593 plane[0].data_offset = 0;
5594 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5595 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5596 plane[extra_idx].bytesused = 0;
5597 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5598 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 -07005599#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005600 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005601#endif
Arun Menon906de572013-06-18 17:01:40 -07005602 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5603 plane[extra_idx].data_offset = 0;
5604 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5605 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5606 return OMX_ErrorBadParameter;
5607 }
5608 buf.m.planes = plane;
5609 buf.length = drv_ctx.num_planes;
5610 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5611 if (rc) {
5612 /*TODO: How to handle this case */
5613 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5614 }
Arun Menon906de572013-06-18 17:01:40 -07005615return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005616}
5617
5618/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005619 FUNCTION
5620 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005621
Arun Menon906de572013-06-18 17:01:40 -07005622 DESCRIPTION
5623 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005624
Arun Menon906de572013-06-18 17:01:40 -07005625 PARAMETERS
5626 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005627
Arun Menon906de572013-06-18 17:01:40 -07005628 RETURN VALUE
5629 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005630
Arun Menon906de572013-06-18 17:01:40 -07005631 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005632OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005633 OMX_IN OMX_CALLBACKTYPE* callbacks,
5634 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005635{
5636
Arun Menon906de572013-06-18 17:01:40 -07005637 m_cb = *callbacks;
5638 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5639 m_cb.EventHandler,m_cb.FillBufferDone);
5640 m_app_data = appData;
5641 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005642}
5643
5644/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005645 FUNCTION
5646 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005647
Arun Menon906de572013-06-18 17:01:40 -07005648 DESCRIPTION
5649 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005650
Arun Menon906de572013-06-18 17:01:40 -07005651 PARAMETERS
5652 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005653
Arun Menon906de572013-06-18 17:01:40 -07005654 RETURN VALUE
5655 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005656
Arun Menon906de572013-06-18 17:01:40 -07005657 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005658OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5659{
5660#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005661 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005662 delete iDivXDrmDecrypt;
5663 iDivXDrmDecrypt=NULL;
5664 }
5665#endif //_ANDROID_
5666
Shalaj Jain286b0062013-02-21 20:35:48 -08005667 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005668 if (OMX_StateLoaded != m_state) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005669 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
Arun Menon906de572013-06-18 17:01:40 -07005670 m_state);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005671 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005672 } else {
5673 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005674 }
5675
5676 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005677 if (m_out_mem_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005678 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005679 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5680 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005681 }
5682#ifdef _ANDROID_ICS_
5683 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5684#endif
5685 }
5686
5687 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005688 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005689 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005690 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5691 if (m_inp_mem_ptr)
5692 free_input_buffer (i,&m_inp_mem_ptr[i]);
5693 else
5694 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005695 }
5696 }
5697 free_input_buffer_header();
5698 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005699 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005700 free(h264_scratch.pBuffer);
5701 h264_scratch.pBuffer = NULL;
5702 }
5703
Arun Menon906de572013-06-18 17:01:40 -07005704 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005705 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005706 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005707 }
5708
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07005709 if (m_frame_parser.mutils) {
5710 DEBUG_PRINT_LOW("\n Free utils parser");
5711 delete (m_frame_parser.mutils);
5712 m_frame_parser.mutils = NULL;
5713 }
5714
Arun Menon906de572013-06-18 17:01:40 -07005715 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005716 free(m_platform_list);
5717 m_platform_list = NULL;
5718 }
Arun Menon906de572013-06-18 17:01:40 -07005719 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005720 free(m_vendor_config.pData);
5721 m_vendor_config.pData = NULL;
5722 }
5723
5724 // Reset counters in mesg queues
5725 m_ftb_q.m_size=0;
5726 m_cmd_q.m_size=0;
5727 m_etb_q.m_size=0;
5728 m_ftb_q.m_read = m_ftb_q.m_write =0;
5729 m_cmd_q.m_read = m_cmd_q.m_write =0;
5730 m_etb_q.m_read = m_etb_q.m_write =0;
5731#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005732 if (m_debug_timestamp) {
5733 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005734 }
5735#endif
5736
5737 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
5738 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07005739 // NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005740 DEBUG_PRINT_HIGH("\n Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07005741
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005742 if (m_debug.infile) {
5743 fclose(m_debug.infile);
5744 m_debug.infile = NULL;
5745 }
5746 if (m_debug.outfile) {
5747 fclose(m_debug.outfile);
5748 m_debug.outfile = NULL;
5749 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005750#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07005751 if (outputExtradataFile)
5752 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005753#endif
Arun Menon906de572013-06-18 17:01:40 -07005754 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
5755 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005756}
5757
5758/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005759 FUNCTION
5760 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07005761
Arun Menon906de572013-06-18 17:01:40 -07005762 DESCRIPTION
5763 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005764
Arun Menon906de572013-06-18 17:01:40 -07005765 PARAMETERS
5766 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005767
Arun Menon906de572013-06-18 17:01:40 -07005768 RETURN VALUE
5769 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005770
Arun Menon906de572013-06-18 17:01:40 -07005771 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005772OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005773 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5774 OMX_IN OMX_U32 port,
5775 OMX_IN OMX_PTR appData,
5776 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005777{
Arun Menon906de572013-06-18 17:01:40 -07005778 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
5779 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
5780 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005781
5782#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005783 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
5784 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005785#else
Arun Menon906de572013-06-18 17:01:40 -07005786 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005787#endif
Arun Menon906de572013-06-18 17:01:40 -07005788 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
5789 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
5790 DEBUG_PRINT_ERROR("\n ");
5791 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005792#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005793 if (m_display_id == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005794 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
5795 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005796 }
5797 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
5798 eglGetProcAddress("eglQueryImageKHR");
5799 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
5800 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
5801 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005802#else //with OMX test app
5803 struct temp_egl {
5804 int pmem_fd;
5805 int offset;
5806 };
5807 struct temp_egl *temp_egl_id = NULL;
5808 void * pmemPtr = (void *) eglImage;
5809 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07005810 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005811 fd = temp_egl_id->pmem_fd;
5812 offset = temp_egl_id->offset;
5813 }
5814#endif
5815 if (fd < 0) {
5816 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
5817 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005818 }
5819 pmem_info.pmem_fd = (OMX_U32) fd;
5820 pmem_info.offset = (OMX_U32) offset;
5821 pmem_entry.entry = (void *) &pmem_info;
5822 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5823 pmem_list.entryList = &pmem_entry;
5824 pmem_list.nEntries = 1;
5825 ouput_egl_buffers = true;
5826 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
5827 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
5828 (OMX_U8 *)pmemPtr)) {
5829 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
5830 return OMX_ErrorInsufficientResources;
5831 }
5832 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005833}
5834
5835/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005836 FUNCTION
5837 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07005838
Arun Menon906de572013-06-18 17:01:40 -07005839 DESCRIPTION
5840 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005841
Arun Menon906de572013-06-18 17:01:40 -07005842 PARAMETERS
5843 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005844
Arun Menon906de572013-06-18 17:01:40 -07005845 RETURN VALUE
5846 OMX Error None if everything is successful.
5847 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005848OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005849 OMX_OUT OMX_U8* role,
5850 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005851{
Arun Menon906de572013-06-18 17:01:40 -07005852 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005853
Arun Menon906de572013-06-18 17:01:40 -07005854 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
5855 if ((0 == index) && role) {
5856 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
5857 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5858 } else {
5859 eRet = OMX_ErrorNoMore;
5860 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005861 }
Arun Menon906de572013-06-18 17:01:40 -07005862 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
5863 if ((0 == index) && role) {
5864 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
5865 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5866 } else {
5867 eRet = OMX_ErrorNoMore;
5868 }
5869 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
5870 if ((0 == index) && role) {
5871 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
5872 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5873 } else {
5874 DEBUG_PRINT_LOW("\n No more roles \n");
5875 eRet = OMX_ErrorNoMore;
5876 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005877 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005878
Arun Menon906de572013-06-18 17:01:40 -07005879 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
5880 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
5881 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07005882
Shalaj Jain273b3e02012-06-22 19:08:03 -07005883 {
Arun Menon906de572013-06-18 17:01:40 -07005884 if ((0 == index) && role) {
5885 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
5886 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5887 } else {
5888 DEBUG_PRINT_LOW("\n No more roles \n");
5889 eRet = OMX_ErrorNoMore;
5890 }
5891 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
5892 if ((0 == index) && role) {
5893 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
5894 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5895 } else {
5896 DEBUG_PRINT_LOW("\n No more roles \n");
5897 eRet = OMX_ErrorNoMore;
5898 }
5899 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
5900 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
5901 ) {
5902 if ((0 == index) && role) {
5903 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
5904 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5905 } else {
5906 DEBUG_PRINT_LOW("\n No more roles \n");
5907 eRet = OMX_ErrorNoMore;
5908 }
5909 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
5910 if ((0 == index) && role) {
5911 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
5912 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5913 } else {
5914 DEBUG_PRINT_LOW("\n No more roles \n");
5915 eRet = OMX_ErrorNoMore;
5916 }
5917 } else {
5918 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
5919 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005920 }
Arun Menon906de572013-06-18 17:01:40 -07005921 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005922}
5923
5924
5925
5926
5927/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005928 FUNCTION
5929 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07005930
Arun Menon906de572013-06-18 17:01:40 -07005931 DESCRIPTION
5932 Checks if entire buffer pool is allocated by IL Client or not.
5933 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005934
Arun Menon906de572013-06-18 17:01:40 -07005935 PARAMETERS
5936 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005937
Arun Menon906de572013-06-18 17:01:40 -07005938 RETURN VALUE
5939 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005940
Arun Menon906de572013-06-18 17:01:40 -07005941 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005942bool omx_vdec::allocate_done(void)
5943{
Arun Menon906de572013-06-18 17:01:40 -07005944 bool bRet = false;
5945 bool bRet_In = false;
5946 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005947
Arun Menon906de572013-06-18 17:01:40 -07005948 bRet_In = allocate_input_done();
5949 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005950
Arun Menon906de572013-06-18 17:01:40 -07005951 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005952 bRet = true;
5953 }
Arun Menon906de572013-06-18 17:01:40 -07005954
5955 return bRet;
5956}
5957/* ======================================================================
5958 FUNCTION
5959 omx_vdec::AllocateInputDone
5960
5961 DESCRIPTION
5962 Checks if I/P buffer pool is allocated by IL Client or not.
5963
5964 PARAMETERS
5965 None.
5966
5967 RETURN VALUE
5968 true/false.
5969
5970 ========================================================================== */
5971bool omx_vdec::allocate_input_done(void)
5972{
5973 bool bRet = false;
5974 unsigned i=0;
5975
5976 if (m_inp_mem_ptr == NULL) {
5977 return bRet;
5978 }
5979 if (m_inp_mem_ptr ) {
5980 for (; i<drv_ctx.ip_buf.actualcount; i++) {
5981 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
5982 break;
5983 }
5984 }
5985 }
5986 if (i == drv_ctx.ip_buf.actualcount) {
5987 bRet = true;
5988 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
5989 }
5990 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
5991 m_inp_bPopulated = OMX_TRUE;
5992 }
5993 return bRet;
5994}
5995/* ======================================================================
5996 FUNCTION
5997 omx_vdec::AllocateOutputDone
5998
5999 DESCRIPTION
6000 Checks if entire O/P buffer pool is allocated by IL Client or not.
6001
6002 PARAMETERS
6003 None.
6004
6005 RETURN VALUE
6006 true/false.
6007
6008 ========================================================================== */
6009bool omx_vdec::allocate_output_done(void)
6010{
6011 bool bRet = false;
6012 unsigned j=0;
6013
6014 if (m_out_mem_ptr == NULL) {
6015 return bRet;
6016 }
6017
6018 if (m_out_mem_ptr) {
6019 for (; j < drv_ctx.op_buf.actualcount; j++) {
6020 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6021 break;
6022 }
6023 }
6024 }
6025
6026 if (j == drv_ctx.op_buf.actualcount) {
6027 bRet = true;
6028 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6029 if (m_out_bEnabled)
6030 m_out_bPopulated = OMX_TRUE;
6031 }
6032
6033 return bRet;
6034}
6035
6036/* ======================================================================
6037 FUNCTION
6038 omx_vdec::ReleaseDone
6039
6040 DESCRIPTION
6041 Checks if IL client has released all the buffers.
6042
6043 PARAMETERS
6044 None.
6045
6046 RETURN VALUE
6047 true/false
6048
6049 ========================================================================== */
6050bool omx_vdec::release_done(void)
6051{
6052 bool bRet = false;
6053
6054 if (release_input_done()) {
6055 if (release_output_done()) {
6056 bRet = true;
6057 }
6058 }
6059 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006060}
6061
6062
6063/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006064 FUNCTION
6065 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006066
Arun Menon906de572013-06-18 17:01:40 -07006067 DESCRIPTION
6068 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006069
Arun Menon906de572013-06-18 17:01:40 -07006070 PARAMETERS
6071 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006072
Arun Menon906de572013-06-18 17:01:40 -07006073 RETURN VALUE
6074 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006075
Arun Menon906de572013-06-18 17:01:40 -07006076 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006077bool omx_vdec::release_output_done(void)
6078{
Arun Menon906de572013-06-18 17:01:40 -07006079 bool bRet = false;
6080 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006081
Arun Menon906de572013-06-18 17:01:40 -07006082 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6083 if (m_out_mem_ptr) {
6084 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6085 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6086 break;
6087 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006088 }
Arun Menon906de572013-06-18 17:01:40 -07006089 if (j == drv_ctx.op_buf.actualcount) {
6090 m_out_bm_count = 0;
6091 bRet = true;
6092 }
6093 } else {
6094 m_out_bm_count = 0;
6095 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006096 }
Arun Menon906de572013-06-18 17:01:40 -07006097 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006098}
6099/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006100 FUNCTION
6101 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006102
Arun Menon906de572013-06-18 17:01:40 -07006103 DESCRIPTION
6104 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006105
Arun Menon906de572013-06-18 17:01:40 -07006106 PARAMETERS
6107 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006108
Arun Menon906de572013-06-18 17:01:40 -07006109 RETURN VALUE
6110 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006111
Arun Menon906de572013-06-18 17:01:40 -07006112 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006113bool omx_vdec::release_input_done(void)
6114{
Arun Menon906de572013-06-18 17:01:40 -07006115 bool bRet = false;
6116 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006117
Arun Menon906de572013-06-18 17:01:40 -07006118 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6119 if (m_inp_mem_ptr) {
6120 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6121 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6122 break;
6123 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006124 }
Arun Menon906de572013-06-18 17:01:40 -07006125 if (j==drv_ctx.ip_buf.actualcount) {
6126 bRet = true;
6127 }
6128 } else {
6129 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006130 }
Arun Menon906de572013-06-18 17:01:40 -07006131 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006132}
6133
6134OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006135 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006136{
Arun Menon906de572013-06-18 17:01:40 -07006137 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6138 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) {
6139 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6140 return OMX_ErrorBadParameter;
6141 } else if (output_flush_progress) {
6142 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6143 buffer->nFilledLen = 0;
6144 buffer->nTimeStamp = 0;
6145 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6146 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6147 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006148 }
6149
Arun Menon906de572013-06-18 17:01:40 -07006150 if (m_debug_extradata) {
6151 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
6152 DEBUG_PRINT_HIGH("\n");
6153 DEBUG_PRINT_HIGH("***************************************************\n");
6154 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
6155 DEBUG_PRINT_HIGH("***************************************************\n");
6156 }
6157
6158 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
6159 DEBUG_PRINT_HIGH("\n");
6160 DEBUG_PRINT_HIGH("***************************************************\n");
6161 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
6162 DEBUG_PRINT_HIGH("***************************************************\n");
6163 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006164 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006165
6166
Arun Menon906de572013-06-18 17:01:40 -07006167 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6168 buffer, buffer->pBuffer);
6169 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006170
Arun Menon906de572013-06-18 17:01:40 -07006171 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6172 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6173 if (!output_flush_progress)
6174 post_event((unsigned)NULL, (unsigned)NULL,
6175 OMX_COMPONENT_GENERATE_EOS_DONE);
6176
6177 if (psource_frame) {
6178 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6179 psource_frame = NULL;
6180 }
6181 if (pdest_frame) {
6182 pdest_frame->nFilledLen = 0;
6183 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6184 (unsigned)NULL);
6185 pdest_frame = NULL;
6186 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006187 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006188
Arun Menon906de572013-06-18 17:01:40 -07006189 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006190 log_output_buffers(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006191
Arun Menon906de572013-06-18 17:01:40 -07006192 /* For use buffer we need to copy the data */
6193 if (!output_flush_progress) {
6194 /* This is the error check for non-recoverable errros */
6195 bool is_duplicate_ts_valid = true;
6196 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006197
Arun Menon906de572013-06-18 17:01:40 -07006198 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6199 output_capability == V4L2_PIX_FMT_MPEG2 ||
6200 output_capability == V4L2_PIX_FMT_DIVX ||
6201 output_capability == V4L2_PIX_FMT_DIVX_311)
6202 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006203
Arun Menon906de572013-06-18 17:01:40 -07006204 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6205 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6206 if (mbaff) {
6207 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306208 }
Arun Menon906de572013-06-18 17:01:40 -07006209 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306210
Arun Menon906de572013-06-18 17:01:40 -07006211 if (buffer->nFilledLen > 0) {
6212 time_stamp_dts.get_next_timestamp(buffer,
6213 is_interlaced && is_duplicate_ts_valid);
6214 if (m_debug_timestamp) {
6215 {
6216 OMX_TICKS expected_ts = 0;
6217 m_timestamp_list.pop_min_ts(expected_ts);
6218 if (is_interlaced && is_duplicate_ts_valid) {
6219 m_timestamp_list.pop_min_ts(expected_ts);
6220 }
6221 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6222 buffer->nTimeStamp, expected_ts);
6223
6224 if (buffer->nTimeStamp != expected_ts) {
6225 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6226 }
6227 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306228 }
Arun Menon906de572013-06-18 17:01:40 -07006229 } else {
6230 m_inp_err_count++;
6231 time_stamp_dts.remove_time_stamp(
6232 buffer->nTimeStamp,
6233 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306234 }
Arun Menon906de572013-06-18 17:01:40 -07006235
6236
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006237 }
Arun Menon906de572013-06-18 17:01:40 -07006238 if (m_cb.FillBufferDone) {
6239 if (buffer->nFilledLen > 0) {
6240 handle_extradata(buffer);
6241 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6242 set_frame_rate(buffer->nTimeStamp);
6243 else if (arbitrary_bytes)
6244 adjust_timestamp(buffer->nTimeStamp);
6245 if (perf_flag) {
6246 if (!proc_frms) {
6247 dec_time.stop();
6248 latency = dec_time.processing_time_us() - latency;
6249 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6250 dec_time.start();
6251 fps_metrics.start();
6252 }
6253 proc_frms++;
6254 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6255 OMX_U64 proc_time = 0;
6256 fps_metrics.stop();
6257 proc_time = fps_metrics.processing_time_us();
6258 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006259 proc_frms, (float)proc_time / 1e6,
6260 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006261 proc_frms = 0;
6262 }
6263 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006264
6265#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006266 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006267
Arun Menon906de572013-06-18 17:01:40 -07006268 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6269 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6270 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6271 buffer->nFilledLen + 3)&(~3));
6272 while (p_extra &&
6273 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
6274 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6275 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6276 if (p_extra->eType == OMX_ExtraDataNone) {
6277 break;
6278 }
6279 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6280 }
6281 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006282#endif
Arun Menon906de572013-06-18 17:01:40 -07006283 }
6284 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6285 prev_ts = LLONG_MAX;
6286 rst_prev_ts = true;
6287 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006288
Arun Menon906de572013-06-18 17:01:40 -07006289 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6290 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6291 buffer->pPlatformPrivate)->entryList->entry;
6292 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006293 OMX_BUFFERHEADERTYPE *il_buffer;
6294 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6295 if (il_buffer)
6296 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6297 else {
6298 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6299 return OMX_ErrorBadParameter;
6300 }
6301 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
6302 } else {
6303 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006304 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006305
Arun Menon906de572013-06-18 17:01:40 -07006306 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006307}
6308
6309OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006310 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006311{
6312
Arun Menon906de572013-06-18 17:01:40 -07006313 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006314 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006315 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006316 }
6317
6318 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006319 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006320 pending_input_buffers--;
6321
Arun Menon906de572013-06-18 17:01:40 -07006322 if (arbitrary_bytes) {
6323 if (pdest_frame == NULL && input_flush_progress == false) {
6324 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6325 pdest_frame = buffer;
6326 buffer->nFilledLen = 0;
6327 buffer->nTimeStamp = LLONG_MAX;
6328 push_input_buffer (hComp);
6329 } else {
6330 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6331 buffer->nFilledLen = 0;
6332 if (!m_input_free_q.insert_entry((unsigned)buffer,
6333 (unsigned)NULL, (unsigned)NULL)) {
6334 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6335 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006336 }
Arun Menon906de572013-06-18 17:01:40 -07006337 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006338 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006339 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006340 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6341 }
6342 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6343 }
6344 return OMX_ErrorNone;
6345}
6346
Shalaj Jain273b3e02012-06-22 19:08:03 -07006347int omx_vdec::async_message_process (void *context, void* message)
6348{
Arun Menon906de572013-06-18 17:01:40 -07006349 omx_vdec* omx = NULL;
6350 struct vdec_msginfo *vdec_msg = NULL;
6351 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6352 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6353 struct vdec_output_frameinfo *output_respbuf = NULL;
6354 int rc=1;
6355 if (context == NULL || message == NULL) {
6356 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6357 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006358 }
Arun Menon906de572013-06-18 17:01:40 -07006359 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006360
Arun Menon906de572013-06-18 17:01:40 -07006361 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006362
Arun Menon906de572013-06-18 17:01:40 -07006363 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006364
Arun Menon906de572013-06-18 17:01:40 -07006365 case VDEC_MSG_EVT_HW_ERROR:
6366 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6367 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6368 break;
6369
6370 case VDEC_MSG_RESP_START_DONE:
6371 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6372 OMX_COMPONENT_GENERATE_START_DONE);
6373 break;
6374
6375 case VDEC_MSG_RESP_STOP_DONE:
6376 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6377 OMX_COMPONENT_GENERATE_STOP_DONE);
6378 break;
6379
6380 case VDEC_MSG_RESP_RESUME_DONE:
6381 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6382 OMX_COMPONENT_GENERATE_RESUME_DONE);
6383 break;
6384
6385 case VDEC_MSG_RESP_PAUSE_DONE:
6386 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6387 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6388 break;
6389
6390 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6391 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6392 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6393 break;
6394 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6395 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6396 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6397 break;
6398 case VDEC_MSG_RESP_INPUT_FLUSHED:
6399 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6400
6401 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6402 vdec_msg->msgdata.input_frame_clientdata; */
6403
6404 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6405 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6406 if (omxhdr == NULL ||
6407 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) {
6408 omxhdr = NULL;
6409 vdec_msg->status_code = VDEC_S_EFATAL;
6410 }
6411 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6412 DEBUG_PRINT_HIGH("Unsupported input");
6413 omx->omx_report_error ();
6414 }
6415 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6416 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6417 }
6418 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6419 OMX_COMPONENT_GENERATE_EBD);
6420 break;
6421 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6422 int64_t *timestamp;
6423 timestamp = (int64_t *) malloc(sizeof(int64_t));
6424 if (timestamp) {
6425 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6426 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6427 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6428 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6429 vdec_msg->msgdata.output_frame.time_stamp);
6430 }
6431 break;
6432 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6433 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6434
6435 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6436 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6437 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6438 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6439 vdec_msg->msgdata.output_frame.pic_type);
6440
6441 if (omxhdr && omxhdr->pOutputPortPrivate &&
6442 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6443 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6444 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) {
6445 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6446 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6447 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6448 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6449 omxhdr->nFlags = 0;
6450
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006451 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006452 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6453 //rc = -1;
6454 }
6455 if (omxhdr->nFilledLen) {
6456 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6457 }
6458 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6459 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6460 } else {
6461 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6462 }
6463 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6464 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6465 }
6466 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6467 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6468 }
6469 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6470 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006471 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006472 omx->time_stamp_dts.remove_time_stamp(
6473 omxhdr->nTimeStamp,
6474 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6475 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006476 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6477 OMX_COMPONENT_GENERATE_FTB);
6478 break;
6479 }
6480 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6481 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6482 }
6483 vdec_msg->msgdata.output_frame.bufferaddr =
6484 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6485 int format_notably_changed = 0;
6486 if (omxhdr->nFilledLen &&
6487 (omxhdr->nFilledLen != omx->prev_n_filled_len)) {
6488 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6489 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6490 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
6491 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6492 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6493 format_notably_changed = 1;
6494 }
6495 }
6496 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6497 vdec_msg->msgdata.output_frame.framesize.left)
6498 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6499 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6500 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6501 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6502 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6503 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6504 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6505 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
6506 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6507 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6508 }
6509 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
6510 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6511 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006512 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6513 omx->drv_ctx.video_resolution.frame_width) {
6514 vdec_msg->msgdata.output_frame.framesize.left = 0;
6515 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6516 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6517 }
6518 }
6519 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6520 omx->drv_ctx.video_resolution.frame_height) {
6521 vdec_msg->msgdata.output_frame.framesize.top = 0;
6522 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6523 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6524 }
6525 }
6526 DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d\n",
6527 vdec_msg->msgdata.output_frame.framesize.left,
6528 vdec_msg->msgdata.output_frame.framesize.top,
6529 vdec_msg->msgdata.output_frame.framesize.right,
6530 vdec_msg->msgdata.output_frame.framesize.bottom,
6531 omx->drv_ctx.video_resolution.frame_width,
6532 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006533 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6534 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6535 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6536 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6537 format_notably_changed = 1;
6538 }
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006539 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d\n",
6540 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6541 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006542 if (format_notably_changed) {
6543 if (omx->is_video_session_supported()) {
6544 omx->post_event (NULL, vdec_msg->status_code,
6545 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6546 } else {
6547 if (!omx->client_buffers.update_buffer_req()) {
6548 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6549 }
6550 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6551 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6552 }
6553 }
6554 if (omxhdr->nFilledLen)
6555 omx->prev_n_filled_len = omxhdr->nFilledLen;
6556
6557 output_respbuf = (struct vdec_output_frameinfo *)\
6558 omxhdr->pOutputPortPrivate;
6559 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6560 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6561 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6562 output_respbuf->pic_type = PICTURE_TYPE_I;
6563 }
6564 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6565 output_respbuf->pic_type = PICTURE_TYPE_P;
6566 }
6567 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6568 output_respbuf->pic_type = PICTURE_TYPE_B;
6569 }
6570
6571 if (omx->output_use_buffer)
6572 memcpy ( omxhdr->pBuffer, (void *)
6573 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6574 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6575 vdec_msg->msgdata.output_frame.len);
6576 } else
6577 omxhdr->nFilledLen = 0;
6578 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6579 OMX_COMPONENT_GENERATE_FBD);
6580 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6581 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6582 OMX_COMPONENT_GENERATE_EOS_DONE);
6583 else
6584 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6585 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6586 break;
6587 case VDEC_MSG_EVT_CONFIG_CHANGED:
6588 DEBUG_PRINT_HIGH("\n Port settings changed");
6589 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6590 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6591 break;
6592 default:
6593 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006594 }
Arun Menon906de572013-06-18 17:01:40 -07006595 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006596}
6597
6598OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006599 OMX_HANDLETYPE hComp,
6600 OMX_BUFFERHEADERTYPE *buffer
6601 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006602{
Arun Menon906de572013-06-18 17:01:40 -07006603 unsigned address,p2,id;
6604 DEBUG_PRINT_LOW("\n Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006605
Arun Menon906de572013-06-18 17:01:40 -07006606 if (buffer == NULL) {
6607 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006608 }
Arun Menon906de572013-06-18 17:01:40 -07006609 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6610 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
6611 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6612
6613 /* return zero length and not an EOS buffer */
6614 /* return buffer if input flush in progress */
6615 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6616 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
6617 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
6618 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6619 return OMX_ErrorNone;
6620 }
6621
6622 if (psource_frame == NULL) {
6623 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
6624 psource_frame = buffer;
6625 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
6626 push_input_buffer (hComp);
6627 } else {
6628 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
6629 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6630 (unsigned)NULL)) {
6631 return OMX_ErrorBadParameter;
6632 }
6633 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006634
6635
Arun Menon906de572013-06-18 17:01:40 -07006636 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006637}
6638
6639OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6640{
Arun Menon906de572013-06-18 17:01:40 -07006641 unsigned address,p2,id;
6642 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006643
Arun Menon906de572013-06-18 17:01:40 -07006644 if (pdest_frame == NULL || psource_frame == NULL) {
6645 /*Check if we have a destination buffer*/
6646 if (pdest_frame == NULL) {
6647 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
6648 if (m_input_free_q.m_size) {
6649 m_input_free_q.pop_entry(&address,&p2,&id);
6650 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6651 pdest_frame->nFilledLen = 0;
6652 pdest_frame->nTimeStamp = LLONG_MAX;
6653 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
6654 }
6655 }
6656
6657 /*Check if we have a destination buffer*/
6658 if (psource_frame == NULL) {
6659 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
6660 if (m_input_pending_q.m_size) {
6661 m_input_pending_q.pop_entry(&address,&p2,&id);
6662 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
6663 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6664 psource_frame->nTimeStamp);
6665 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6666 psource_frame->nFlags,psource_frame->nFilledLen);
6667
6668 }
6669 }
6670
Shalaj Jain273b3e02012-06-22 19:08:03 -07006671 }
6672
Arun Menon906de572013-06-18 17:01:40 -07006673 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6674 switch (codec_type_parse) {
6675 case CODEC_TYPE_MPEG4:
6676 case CODEC_TYPE_H263:
6677 case CODEC_TYPE_MPEG2:
6678 ret = push_input_sc_codec(hComp);
6679 break;
6680 case CODEC_TYPE_H264:
6681 ret = push_input_h264(hComp);
6682 break;
6683 case CODEC_TYPE_VC1:
6684 ret = push_input_vc1(hComp);
6685 break;
6686 default:
6687 break;
6688 }
6689 if (ret != OMX_ErrorNone) {
6690 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
6691 omx_report_error ();
6692 break;
6693 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006694 }
6695
Arun Menon906de572013-06-18 17:01:40 -07006696 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006697}
6698
6699OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
6700{
Arun Menon906de572013-06-18 17:01:40 -07006701 OMX_U32 partial_frame = 1;
6702 OMX_BOOL generate_ebd = OMX_TRUE;
6703 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006704
Arun Menon906de572013-06-18 17:01:40 -07006705 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
6706 psource_frame,psource_frame->nTimeStamp);
6707 if (m_frame_parser.parse_sc_frame(psource_frame,
6708 pdest_frame,&partial_frame) == -1) {
6709 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
6710 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006711 }
Arun Menon906de572013-06-18 17:01:40 -07006712
6713 if (partial_frame == 0) {
6714 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
6715 pdest_frame->nFilledLen,psource_frame,frame_count);
6716
6717
6718 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
6719 /*First Parsed buffer will have only header Hence skip*/
6720 if (frame_count == 0) {
6721 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
6722
6723 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
6724 codec_type_parse == CODEC_TYPE_DIVX) {
6725 mp4StreamType psBits;
6726 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
6727 psBits.numBytes = pdest_frame->nFilledLen;
6728 mp4_headerparser.parseHeader(&psBits);
6729 }
6730
6731 frame_count++;
6732 } else {
6733 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6734 if (pdest_frame->nFilledLen) {
6735 /*Push the frame to the Decoder*/
6736 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6737 return OMX_ErrorBadParameter;
6738 }
6739 frame_count++;
6740 pdest_frame = NULL;
6741
6742 if (m_input_free_q.m_size) {
6743 m_input_free_q.pop_entry(&address,&p2,&id);
6744 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6745 pdest_frame->nFilledLen = 0;
6746 }
6747 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
6748 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
6749 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
6750 (unsigned)NULL);
6751 pdest_frame = NULL;
6752 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006753 }
Arun Menon906de572013-06-18 17:01:40 -07006754 } else {
6755 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
6756 /*Check if Destination Buffer is full*/
6757 if (pdest_frame->nAllocLen ==
6758 pdest_frame->nFilledLen + pdest_frame->nOffset) {
6759 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
6760 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006761 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006762 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006763
Arun Menon906de572013-06-18 17:01:40 -07006764 if (psource_frame->nFilledLen == 0) {
6765 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6766 if (pdest_frame) {
6767 pdest_frame->nFlags |= psource_frame->nFlags;
6768 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
6769 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6770 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6771 pdest_frame->nFilledLen,frame_count++);
6772 /*Push the frame to the Decoder*/
6773 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6774 return OMX_ErrorBadParameter;
6775 }
6776 frame_count++;
6777 pdest_frame = NULL;
6778 } else {
6779 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
6780 generate_ebd = OMX_FALSE;
6781 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006782 }
Arun Menon906de572013-06-18 17:01:40 -07006783 if (generate_ebd) {
6784 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
6785 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6786 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006787
Arun Menon906de572013-06-18 17:01:40 -07006788 if (m_input_pending_q.m_size) {
6789 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6790 m_input_pending_q.pop_entry(&address,&p2,&id);
6791 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6792 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6793 psource_frame->nTimeStamp);
6794 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6795 psource_frame->nFlags,psource_frame->nFilledLen);
6796 }
6797 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006798 }
Arun Menon906de572013-06-18 17:01:40 -07006799 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006800}
6801
6802OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
6803{
Arun Menon906de572013-06-18 17:01:40 -07006804 OMX_U32 partial_frame = 1;
6805 unsigned address = 0, p2 = 0, id = 0;
6806 OMX_BOOL isNewFrame = OMX_FALSE;
6807 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006808
Arun Menon906de572013-06-18 17:01:40 -07006809 if (h264_scratch.pBuffer == NULL) {
6810 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
6811 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006812 }
Arun Menon906de572013-06-18 17:01:40 -07006813 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
6814 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
6815 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
6816 if (h264_scratch.nFilledLen && look_ahead_nal) {
6817 look_ahead_nal = false;
6818 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6819 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006820 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6821 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6822 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Arun Menon906de572013-06-18 17:01:40 -07006823 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006824 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006825 } else {
6826 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006827 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006828 }
Arun Menon906de572013-06-18 17:01:40 -07006829 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07006830
6831 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
6832 in EOS flag getting associated with the destination
6833 */
6834 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
6835 pdest_frame->nFilledLen) {
6836 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
6837 generate_ebd = OMX_FALSE;
6838 }
6839
Arun Menon906de572013-06-18 17:01:40 -07006840 if (nal_length == 0) {
6841 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
6842 if (m_frame_parser.parse_sc_frame(psource_frame,
6843 &h264_scratch,&partial_frame) == -1) {
6844 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006845 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006846 }
Arun Menon906de572013-06-18 17:01:40 -07006847 } else {
6848 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
6849 if (m_frame_parser.parse_h264_nallength(psource_frame,
6850 &h264_scratch,&partial_frame) == -1) {
6851 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
6852 return OMX_ErrorBadParameter;
6853 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006854 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006855
Arun Menon906de572013-06-18 17:01:40 -07006856 if (partial_frame == 0) {
6857 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
6858 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
6859 nal_count++;
6860 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
6861 h264_scratch.nFlags = psource_frame->nFlags;
6862 } else {
6863 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
6864 if (h264_scratch.nFilledLen) {
6865 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
6866 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006867#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07006868 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6869 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
6870 h264_scratch.nFilledLen, NALU_TYPE_SEI);
6871 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
6872 // If timeinfo is present frame info from SEI is already processed
6873 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
6874 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006875#endif
Arun Menon906de572013-06-18 17:01:40 -07006876 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
6877 nal_count++;
6878 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
6879 pdest_frame->nTimeStamp = h264_last_au_ts;
6880 pdest_frame->nFlags = h264_last_au_flags;
6881#ifdef PANSCAN_HDLR
6882 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
6883 h264_parser->update_panscan_data(h264_last_au_ts);
6884#endif
6885 }
6886 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
6887 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
6888 h264_last_au_ts = h264_scratch.nTimeStamp;
6889 h264_last_au_flags = h264_scratch.nFlags;
6890#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
6891 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
6892 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
6893 if (!VALID_TS(h264_last_au_ts))
6894 h264_last_au_ts = ts_in_sei;
6895 }
6896#endif
6897 } else
6898 h264_last_au_ts = LLONG_MAX;
6899 }
6900
6901 if (!isNewFrame) {
6902 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6903 h264_scratch.nFilledLen) {
6904 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
6905 h264_scratch.nFilledLen);
6906 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6907 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6908 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6909 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
6910 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6911 h264_scratch.nFilledLen = 0;
6912 } else {
6913 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
6914 return OMX_ErrorBadParameter;
6915 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07006916 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07006917 look_ahead_nal = true;
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05306918 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07006919 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6920 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6921 pdest_frame->nFilledLen,frame_count++);
6922
6923 if (pdest_frame->nFilledLen == 0) {
6924 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
6925 look_ahead_nal = false;
6926 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6927 h264_scratch.nFilledLen) {
6928 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6929 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6930 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6931 h264_scratch.nFilledLen = 0;
6932 } else {
6933 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
6934 return OMX_ErrorBadParameter;
6935 }
6936 } else {
6937 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
6938 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
6939 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6940 }
6941 /*Push the frame to the Decoder*/
6942 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6943 return OMX_ErrorBadParameter;
6944 }
6945 //frame_count++;
6946 pdest_frame = NULL;
6947 if (m_input_free_q.m_size) {
6948 m_input_free_q.pop_entry(&address,&p2,&id);
6949 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6950 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
6951 pdest_frame->nFilledLen = 0;
6952 pdest_frame->nFlags = 0;
6953 pdest_frame->nTimeStamp = LLONG_MAX;
6954 }
6955 }
6956 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006957 }
Arun Menon906de572013-06-18 17:01:40 -07006958 } else {
6959 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
6960 /*Check if Destination Buffer is full*/
6961 if (h264_scratch.nAllocLen ==
6962 h264_scratch.nFilledLen + h264_scratch.nOffset) {
6963 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
6964 return OMX_ErrorStreamCorrupt;
6965 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006966 }
Arun Menon906de572013-06-18 17:01:40 -07006967
6968 if (!psource_frame->nFilledLen) {
6969 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
6970
6971 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6972 if (pdest_frame) {
6973 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
6974 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6975 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07006976 if(pdest_frame->nFilledLen == 0) {
6977 /* No residual frame from before, send whatever
6978 * we have left */
6979 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6980 h264_scratch.pBuffer, h264_scratch.nFilledLen);
6981 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6982 h264_scratch.nFilledLen = 0;
6983 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
6984 } else {
6985 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
6986 if(!isNewFrame) {
6987 /* Have a residual frame, but we know that the
6988 * AU in this frame is belonging to whatever
6989 * frame we had left over. So append it */
6990 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6991 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6992 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6993 h264_scratch.nFilledLen = 0;
6994 pdest_frame->nTimeStamp = h264_last_au_ts;
6995 } else {
6996 /* Completely new frame, let's just push what
6997 * we have now. The resulting EBD would trigger
6998 * another push */
6999 generate_ebd = OMX_FALSE;
7000 pdest_frame->nTimeStamp = h264_last_au_ts;
7001 h264_last_au_ts = h264_scratch.nTimeStamp;
7002 }
7003 }
Arun Menon906de572013-06-18 17:01:40 -07007004 } else {
7005 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7006 return OMX_ErrorBadParameter;
7007 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007008
7009 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7010 if(generate_ebd == OMX_TRUE) {
7011 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7012 }
Arun Menon906de572013-06-18 17:01:40 -07007013
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05307014 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007015 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7016 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7017#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7018 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7019 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7020 if (!VALID_TS(pdest_frame->nTimeStamp))
7021 pdest_frame->nTimeStamp = ts_in_sei;
7022 }
7023#endif
7024 /*Push the frame to the Decoder*/
7025 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7026 return OMX_ErrorBadParameter;
7027 }
7028 frame_count++;
7029 pdest_frame = NULL;
7030 } else {
7031 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
7032 pdest_frame,h264_scratch.nFilledLen);
7033 generate_ebd = OMX_FALSE;
7034 }
7035 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007036 }
Arun Menon906de572013-06-18 17:01:40 -07007037 if (generate_ebd && !psource_frame->nFilledLen) {
7038 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7039 psource_frame = NULL;
7040 if (m_input_pending_q.m_size) {
7041 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7042 m_input_pending_q.pop_entry(&address,&p2,&id);
7043 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7044 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
7045 psource_frame->nFlags,psource_frame->nFilledLen);
7046 }
7047 }
7048 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007049}
7050
7051OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7052{
7053 OMX_U8 *buf, *pdest;
7054 OMX_U32 partial_frame = 1;
7055 OMX_U32 buf_len, dest_len;
7056
Arun Menon906de572013-06-18 17:01:40 -07007057 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007058 first_frame = 1;
7059 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
Arun Menon906de572013-06-18 17:01:40 -07007060 if (!m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007061 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7062 buf = psource_frame->pBuffer;
7063 buf_len = psource_frame->nFilledLen;
7064
7065 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007066 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007067 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007068 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007069 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007070 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007071 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7072 return OMX_ErrorStreamCorrupt;
7073 }
Arun Menon906de572013-06-18 17:01:40 -07007074 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007075 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7076 pdest_frame->nOffset;
7077 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007078 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007079
Arun Menon906de572013-06-18 17:01:40 -07007080 if (dest_len < m_vendor_config.nDataSize) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007081 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7082 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007083 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007084 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7085 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7086 }
7087 }
7088 }
7089
Arun Menon906de572013-06-18 17:01:40 -07007090 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007091 case VC1_AP:
7092 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007093 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007094 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7095 return OMX_ErrorBadParameter;
7096 }
Arun Menon906de572013-06-18 17:01:40 -07007097 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007098
7099 case VC1_SP_MP_RCV:
7100 default:
7101 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7102 return OMX_ErrorBadParameter;
7103 }
7104 return OMX_ErrorNone;
7105}
7106
David Ng38e2d232013-03-15 20:05:58 -07007107#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007108bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007109 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007110{
Arun Menon906de572013-06-18 17:01:40 -07007111 struct pmem_allocation allocation;
7112 allocation.size = buffer_size;
7113 allocation.align = clip2(alignment);
7114 if (allocation.align < 4096) {
7115 allocation.align = 4096;
7116 }
7117 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
7118 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7119 allocation.align, allocation.size);
7120 return false;
7121 }
7122 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007123}
David Ng38e2d232013-03-15 20:05:58 -07007124#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007125#ifdef USE_ION
7126int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007127 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7128 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007129{
Arun Menon906de572013-06-18 17:01:40 -07007130 int fd = -EINVAL;
7131 int rc = -EINVAL;
7132 int ion_dev_flag;
7133 struct vdec_ion ion_buf_info;
7134 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7135 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7136 return -EINVAL;
7137 }
7138 ion_dev_flag = O_RDONLY;
7139 fd = open (MEM_DEVICE, ion_dev_flag);
7140 if (fd < 0) {
7141 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7142 return fd;
7143 }
7144 alloc_data->flags = 0;
7145 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7146 alloc_data->flags |= ION_FLAG_CACHED;
7147 }
7148 alloc_data->len = buffer_size;
7149 alloc_data->align = clip2(alignment);
7150 if (alloc_data->align < 4096) {
7151 alloc_data->align = 4096;
7152 }
7153 if ((secure_mode) && (flag & ION_SECURE))
7154 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007155
Arun Menon906de572013-06-18 17:01:40 -07007156 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7157 if (secure_mode)
7158 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7159 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7160 if (rc || !alloc_data->handle) {
7161 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7162 alloc_data->handle = NULL;
7163 close(fd);
7164 fd = -ENOMEM;
7165 return fd;
7166 }
7167 fd_data->handle = alloc_data->handle;
7168 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7169 if (rc) {
7170 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7171 ion_buf_info.ion_alloc_data = *alloc_data;
7172 ion_buf_info.ion_device_fd = fd;
7173 ion_buf_info.fd_ion_data = *fd_data;
7174 free_ion_memory(&ion_buf_info);
7175 fd_data->fd =-1;
7176 close(fd);
7177 fd = -ENOMEM;
7178 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007179
Arun Menon906de572013-06-18 17:01:40 -07007180 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007181}
7182
Arun Menon906de572013-06-18 17:01:40 -07007183void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7184{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007185
Arun Menon906de572013-06-18 17:01:40 -07007186 if (!buf_ion_info) {
7187 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7188 return;
7189 }
7190 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7191 &buf_ion_info->ion_alloc_data.handle)) {
7192 DEBUG_PRINT_ERROR("\n ION: free failed" );
7193 }
7194 close(buf_ion_info->ion_device_fd);
7195 buf_ion_info->ion_device_fd = -1;
7196 buf_ion_info->ion_alloc_data.handle = NULL;
7197 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007198}
7199#endif
7200void omx_vdec::free_output_buffer_header()
7201{
Arun Menon906de572013-06-18 17:01:40 -07007202 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7203 output_use_buffer = false;
7204 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007205
Arun Menon906de572013-06-18 17:01:40 -07007206 if (m_out_mem_ptr) {
7207 free (m_out_mem_ptr);
7208 m_out_mem_ptr = NULL;
7209 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007210
Arun Menon906de572013-06-18 17:01:40 -07007211 if (m_platform_list) {
7212 free(m_platform_list);
7213 m_platform_list = NULL;
7214 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007215
Arun Menon906de572013-06-18 17:01:40 -07007216 if (drv_ctx.ptr_respbuffer) {
7217 free (drv_ctx.ptr_respbuffer);
7218 drv_ctx.ptr_respbuffer = NULL;
7219 }
7220 if (drv_ctx.ptr_outputbuffer) {
7221 free (drv_ctx.ptr_outputbuffer);
7222 drv_ctx.ptr_outputbuffer = NULL;
7223 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007224#ifdef USE_ION
7225 if (drv_ctx.op_buf_ion_info) {
7226 DEBUG_PRINT_LOW("\n Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007227 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007228 drv_ctx.op_buf_ion_info = NULL;
7229 }
7230#endif
7231}
7232
7233void omx_vdec::free_input_buffer_header()
7234{
7235 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007236 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007237 if (m_inp_heap_ptr) {
7238 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7239 free (m_inp_heap_ptr);
7240 m_inp_heap_ptr = NULL;
7241 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007242
Arun Menon906de572013-06-18 17:01:40 -07007243 if (m_phdr_pmem_ptr) {
7244 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7245 free (m_phdr_pmem_ptr);
7246 m_phdr_pmem_ptr = NULL;
7247 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007248 }
Arun Menon906de572013-06-18 17:01:40 -07007249 if (m_inp_mem_ptr) {
7250 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7251 free (m_inp_mem_ptr);
7252 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007253 }
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007254 /* We just freed all the buffer headers, every thing in m_input_free_q
7255 * is now invalid */
7256 while (m_input_free_q.m_size) {
7257 unsigned address, p2, id;
7258 m_input_free_q.pop_entry(&address, &p2, &id);
7259 }
Arun Menon906de572013-06-18 17:01:40 -07007260 if (drv_ctx.ptr_inputbuffer) {
7261 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7262 free (drv_ctx.ptr_inputbuffer);
7263 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007264 }
7265#ifdef USE_ION
7266 if (drv_ctx.ip_buf_ion_info) {
7267 DEBUG_PRINT_LOW("\n Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007268 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007269 drv_ctx.ip_buf_ion_info = NULL;
7270 }
7271#endif
7272}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007273
7274int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007275{
Arun Menon906de572013-06-18 17:01:40 -07007276 enum v4l2_buf_type btype;
7277 int rc = 0;
7278 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007279
Arun Menon906de572013-06-18 17:01:40 -07007280 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7281 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7282 v4l2_port = OUTPUT_PORT;
7283 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7284 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7285 v4l2_port = CAPTURE_PORT;
7286 } else if (port == OMX_ALL) {
7287 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7288 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007289
Arun Menon906de572013-06-18 17:01:40 -07007290 if (!rc_input)
7291 return rc_input;
7292 else
7293 return rc_output;
7294 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007295
Arun Menon906de572013-06-18 17:01:40 -07007296 if (!streaming[v4l2_port]) {
7297 // already streamed off, warn and move on
7298 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7299 " which is already streamed off", v4l2_port);
7300 return 0;
7301 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007302
Arun Menon906de572013-06-18 17:01:40 -07007303 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007304
Arun Menon906de572013-06-18 17:01:40 -07007305 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7306 if (rc) {
7307 /*TODO: How to handle this case */
7308 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
7309 } else {
7310 streaming[v4l2_port] = false;
7311 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007312
Arun Menon906de572013-06-18 17:01:40 -07007313 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007314}
7315
7316OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7317{
Arun Menon906de572013-06-18 17:01:40 -07007318 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7319 struct v4l2_requestbuffers bufreq;
7320 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7321 struct v4l2_format fmt;
7322 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007323 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007324 buffer_prop->actualcount, buffer_prop->buffer_size);
7325 bufreq.memory = V4L2_MEMORY_USERPTR;
7326 bufreq.count = 1;
7327 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7328 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7329 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7330 fmt.fmt.pix_mp.pixelformat = output_capability;
7331 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7332 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7333 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7334 fmt.fmt.pix_mp.pixelformat = capture_capability;
7335 } else {
7336 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007337 }
Arun Menon906de572013-06-18 17:01:40 -07007338 if (eRet==OMX_ErrorNone) {
7339 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007340 }
Arun Menon906de572013-06-18 17:01:40 -07007341 if (ret) {
7342 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7343 /*TODO: How to handle this case */
7344 eRet = OMX_ErrorInsufficientResources;
7345 return eRet;
7346 } else {
7347 buffer_prop->actualcount = bufreq.count;
7348 buffer_prop->mincount = bufreq.count;
7349 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007350 }
Arun Menon906de572013-06-18 17:01:40 -07007351 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7352 buffer_prop->actualcount, buffer_prop->buffer_size);
7353
7354 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7355 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7356
7357 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7358
7359 update_resolution(fmt.fmt.pix_mp.width,
7360 fmt.fmt.pix_mp.height,
7361 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7362 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7363 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7364 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
7365 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
7366
7367 if (ret) {
7368 /*TODO: How to handle this case */
7369 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7370 eRet = OMX_ErrorInsufficientResources;
7371 } else {
7372 int extra_idx = 0;
7373
7374 eRet = is_video_session_supported();
7375 if (eRet)
7376 return eRet;
7377
7378 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7379 buf_size = buffer_prop->buffer_size;
7380 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7381 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7382 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7383 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7384 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7385 return OMX_ErrorBadParameter;
7386 }
7387 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7388 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7389 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7390 }
7391 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7392 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7393 }
7394 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7395 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7396 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7397 client_extra_data_size);
7398 }
7399 if (client_extra_data_size) {
7400 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7401 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7402 }
7403 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7404 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7405 drv_ctx.extradata_info.buffer_size = extra_data_size;
7406 buf_size += client_extra_data_size;
7407 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7408 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7409 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7410 if (in_reconfig) // BufReq will be set to driver when port is disabled
7411 buffer_prop->buffer_size = buf_size;
7412 else if (buf_size != buffer_prop->buffer_size) {
7413 buffer_prop->buffer_size = buf_size;
7414 eRet = set_buffer_req(buffer_prop);
7415 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007416 }
Arun Menon906de572013-06-18 17:01:40 -07007417 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7418 buffer_prop->actualcount, buffer_prop->buffer_size);
7419 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007420}
7421
7422OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7423{
Arun Menon906de572013-06-18 17:01:40 -07007424 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7425 unsigned buf_size = 0;
7426 struct v4l2_format fmt;
7427 struct v4l2_requestbuffers bufreq;
7428 int ret;
7429 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7430 buffer_prop->actualcount, buffer_prop->buffer_size);
7431 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7432 if (buf_size != buffer_prop->buffer_size) {
7433 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7434 buffer_prop->buffer_size, buf_size);
7435 eRet = OMX_ErrorBadParameter;
7436 } else {
7437 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7438 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007439
Arun Menon906de572013-06-18 17:01:40 -07007440 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7441 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7442 fmt.fmt.pix_mp.pixelformat = output_capability;
7443 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7444 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7445 fmt.fmt.pix_mp.pixelformat = capture_capability;
7446 } else {
7447 eRet = OMX_ErrorBadParameter;
7448 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007449
Arun Menon906de572013-06-18 17:01:40 -07007450 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7451 if (ret) {
7452 /*TODO: How to handle this case */
7453 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7454 eRet = OMX_ErrorInsufficientResources;
7455 }
7456
7457 bufreq.memory = V4L2_MEMORY_USERPTR;
7458 bufreq.count = buffer_prop->actualcount;
7459 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7460 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7461 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7462 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7463 } else {
7464 eRet = OMX_ErrorBadParameter;
7465 }
7466
7467 if (eRet==OMX_ErrorNone) {
7468 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7469 }
7470
7471 if (ret) {
7472 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7473 /*TODO: How to handle this case */
7474 eRet = OMX_ErrorInsufficientResources;
7475 } else if (bufreq.count < buffer_prop->actualcount) {
7476 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7477 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7478 buffer_prop->actualcount, bufreq.count);
7479 eRet = OMX_ErrorInsufficientResources;
7480 } else {
7481 if (!client_buffers.update_buffer_req()) {
7482 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7483 eRet = OMX_ErrorInsufficientResources;
7484 }
7485 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007486 }
Arun Menon906de572013-06-18 17:01:40 -07007487 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007488}
7489
Shalaj Jain273b3e02012-06-22 19:08:03 -07007490OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7491{
Arun Menon906de572013-06-18 17:01:40 -07007492 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7493 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007494}
7495
7496OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7497{
Arun Menon906de572013-06-18 17:01:40 -07007498 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7499 if (!portDefn) {
7500 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007501 }
Arun Menon906de572013-06-18 17:01:40 -07007502 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
7503 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7504 portDefn->nSize = sizeof(portDefn);
7505 portDefn->eDomain = OMX_PortDomainVideo;
7506 if (drv_ctx.frame_rate.fps_denominator > 0)
7507 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7508 drv_ctx.frame_rate.fps_denominator;
7509 else {
7510 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7511 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007512 }
Arun Menon906de572013-06-18 17:01:40 -07007513 if (0 == portDefn->nPortIndex) {
7514 portDefn->eDir = OMX_DirInput;
7515 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7516 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7517 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7518 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7519 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7520 portDefn->bEnabled = m_inp_bEnabled;
7521 portDefn->bPopulated = m_inp_bPopulated;
7522 } else if (1 == portDefn->nPortIndex) {
7523 unsigned int buf_size = 0;
7524 if (!client_buffers.update_buffer_req()) {
7525 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
7526 return OMX_ErrorHardware;
7527 }
7528 if (!client_buffers.get_buffer_req(buf_size)) {
7529 DEBUG_PRINT_ERROR("\n update buffer requirements");
7530 return OMX_ErrorHardware;
7531 }
7532 portDefn->nBufferSize = buf_size;
7533 portDefn->eDir = OMX_DirOutput;
7534 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7535 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7536 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7537 portDefn->bEnabled = m_out_bEnabled;
7538 portDefn->bPopulated = m_out_bPopulated;
7539 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
7540 DEBUG_PRINT_ERROR("\n Error in getting color format");
7541 return OMX_ErrorHardware;
7542 }
7543 } else {
7544 portDefn->eDir = OMX_DirMax;
7545 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7546 (int)portDefn->nPortIndex);
7547 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007548 }
Arun Menon906de572013-06-18 17:01:40 -07007549 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7550 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7551 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7552 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7553 DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
7554 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
7555 portDefn->format.video.nFrameHeight,
7556 portDefn->format.video.nStride,
7557 portDefn->format.video.nSliceHeight);
7558 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007559
7560}
7561
7562OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7563{
Arun Menon906de572013-06-18 17:01:40 -07007564 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7565 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7566 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007567
Arun Menon906de572013-06-18 17:01:40 -07007568 if (!m_out_mem_ptr) {
7569 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
7570 int nBufHdrSize = 0;
7571 int nPlatformEntrySize = 0;
7572 int nPlatformListSize = 0;
7573 int nPMEMInfoSize = 0;
7574 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7575 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7576 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007577
Arun Menon906de572013-06-18 17:01:40 -07007578 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
7579 drv_ctx.op_buf.actualcount);
7580 nBufHdrSize = drv_ctx.op_buf.actualcount *
7581 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007582
Arun Menon906de572013-06-18 17:01:40 -07007583 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7584 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7585 nPlatformListSize = drv_ctx.op_buf.actualcount *
7586 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7587 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7588 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007589
Arun Menon906de572013-06-18 17:01:40 -07007590 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
7591 sizeof(OMX_BUFFERHEADERTYPE),
7592 nPMEMInfoSize,
7593 nPlatformListSize);
7594 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
7595 m_out_bm_count);
7596 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7597 // Alloc mem for platform specific info
7598 char *pPtr=NULL;
7599 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7600 nPMEMInfoSize,1);
7601 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7602 calloc (sizeof(struct vdec_bufferpayload),
7603 drv_ctx.op_buf.actualcount);
7604 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7605 calloc (sizeof (struct vdec_output_frameinfo),
7606 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007607#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007608 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7609 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007610#endif
7611
Arun Menon906de572013-06-18 17:01:40 -07007612 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7613 && drv_ctx.ptr_respbuffer) {
7614 bufHdr = m_out_mem_ptr;
7615 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7616 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7617 (((char *) m_platform_list) + nPlatformListSize);
7618 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7619 (((char *) m_platform_entry) + nPlatformEntrySize);
7620 pPlatformList = m_platform_list;
7621 pPlatformEntry = m_platform_entry;
7622 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007623
Arun Menon906de572013-06-18 17:01:40 -07007624 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007625
Arun Menon906de572013-06-18 17:01:40 -07007626 // Settting the entire storage nicely
7627 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
7628 m_out_mem_ptr,pPlatformEntry);
7629 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
7630 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7631 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7632 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7633 // Set the values when we determine the right HxW param
7634 bufHdr->nAllocLen = 0;
7635 bufHdr->nFilledLen = 0;
7636 bufHdr->pAppPrivate = NULL;
7637 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7638 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7639 pPlatformEntry->entry = pPMEMInfo;
7640 // Initialize the Platform List
7641 pPlatformList->nEntries = 1;
7642 pPlatformList->entryList = pPlatformEntry;
7643 // Keep pBuffer NULL till vdec is opened
7644 bufHdr->pBuffer = NULL;
7645 pPMEMInfo->offset = 0;
7646 pPMEMInfo->pmem_fd = 0;
7647 bufHdr->pPlatformPrivate = pPlatformList;
7648 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007649#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007650 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007651#endif
Arun Menon906de572013-06-18 17:01:40 -07007652 /*Create a mapping between buffers*/
7653 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7654 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7655 &drv_ctx.ptr_outputbuffer[i];
7656 // Move the buffer and buffer header pointers
7657 bufHdr++;
7658 pPMEMInfo++;
7659 pPlatformEntry++;
7660 pPlatformList++;
7661 }
7662 } else {
7663 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
7664 m_out_mem_ptr, pPtr);
7665 if (m_out_mem_ptr) {
7666 free(m_out_mem_ptr);
7667 m_out_mem_ptr = NULL;
7668 }
7669 if (pPtr) {
7670 free(pPtr);
7671 pPtr = NULL;
7672 }
7673 if (drv_ctx.ptr_outputbuffer) {
7674 free(drv_ctx.ptr_outputbuffer);
7675 drv_ctx.ptr_outputbuffer = NULL;
7676 }
7677 if (drv_ctx.ptr_respbuffer) {
7678 free(drv_ctx.ptr_respbuffer);
7679 drv_ctx.ptr_respbuffer = NULL;
7680 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007681#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007682 if (drv_ctx.op_buf_ion_info) {
7683 DEBUG_PRINT_LOW("\n Free o/p ion context");
7684 free(drv_ctx.op_buf_ion_info);
7685 drv_ctx.op_buf_ion_info = NULL;
7686 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007687#endif
Arun Menon906de572013-06-18 17:01:40 -07007688 eRet = OMX_ErrorInsufficientResources;
7689 }
7690 } else {
7691 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007692 }
Arun Menon906de572013-06-18 17:01:40 -07007693 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007694}
7695
7696void omx_vdec::complete_pending_buffer_done_cbs()
7697{
Arun Menon906de572013-06-18 17:01:40 -07007698 unsigned p1;
7699 unsigned p2;
7700 unsigned ident;
7701 omx_cmd_queue tmp_q, pending_bd_q;
7702 pthread_mutex_lock(&m_lock);
7703 // pop all pending GENERATE FDB from ftb queue
7704 while (m_ftb_q.m_size) {
7705 m_ftb_q.pop_entry(&p1,&p2,&ident);
7706 if (ident == OMX_COMPONENT_GENERATE_FBD) {
7707 pending_bd_q.insert_entry(p1,p2,ident);
7708 } else {
7709 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007710 }
Arun Menon906de572013-06-18 17:01:40 -07007711 }
7712 //return all non GENERATE FDB to ftb queue
7713 while (tmp_q.m_size) {
7714 tmp_q.pop_entry(&p1,&p2,&ident);
7715 m_ftb_q.insert_entry(p1,p2,ident);
7716 }
7717 // pop all pending GENERATE EDB from etb queue
7718 while (m_etb_q.m_size) {
7719 m_etb_q.pop_entry(&p1,&p2,&ident);
7720 if (ident == OMX_COMPONENT_GENERATE_EBD) {
7721 pending_bd_q.insert_entry(p1,p2,ident);
7722 } else {
7723 tmp_q.insert_entry(p1,p2,ident);
7724 }
7725 }
7726 //return all non GENERATE FDB to etb queue
7727 while (tmp_q.m_size) {
7728 tmp_q.pop_entry(&p1,&p2,&ident);
7729 m_etb_q.insert_entry(p1,p2,ident);
7730 }
7731 pthread_mutex_unlock(&m_lock);
7732 // process all pending buffer dones
7733 while (pending_bd_q.m_size) {
7734 pending_bd_q.pop_entry(&p1,&p2,&ident);
7735 switch (ident) {
7736 case OMX_COMPONENT_GENERATE_EBD:
7737 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
7738 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
7739 omx_report_error ();
7740 }
7741 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007742
Arun Menon906de572013-06-18 17:01:40 -07007743 case OMX_COMPONENT_GENERATE_FBD:
7744 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
7745 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
7746 omx_report_error ();
7747 }
7748 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007749 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007750 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007751}
7752
7753void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
7754{
Arun Menon906de572013-06-18 17:01:40 -07007755 OMX_U32 new_frame_interval = 0;
7756 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
7757 && llabs(act_timestamp - prev_ts) > 2000) {
7758 new_frame_interval = client_set_fps ? frm_int :
7759 llabs(act_timestamp - prev_ts);
7760 if (new_frame_interval < frm_int || frm_int == 0) {
7761 frm_int = new_frame_interval;
7762 if (frm_int) {
7763 drv_ctx.frame_rate.fps_numerator = 1e6;
7764 drv_ctx.frame_rate.fps_denominator = frm_int;
7765 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
7766 frm_int, drv_ctx.frame_rate.fps_numerator /
7767 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007768
Arun Menon906de572013-06-18 17:01:40 -07007769 /* We need to report the difference between this FBD and the previous FBD
7770 * back to the driver for clock scaling purposes. */
7771 struct v4l2_outputparm oparm;
7772 /*XXX: we're providing timing info as seconds per frame rather than frames
7773 * per second.*/
7774 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
7775 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007776
Arun Menon906de572013-06-18 17:01:40 -07007777 struct v4l2_streamparm sparm;
7778 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7779 sparm.parm.output = oparm;
7780 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
7781 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
7782 performance might be affected");
7783 }
7784
7785 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007786 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007787 }
Arun Menon906de572013-06-18 17:01:40 -07007788 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007789}
7790
7791void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
7792{
Arun Menon906de572013-06-18 17:01:40 -07007793 if (rst_prev_ts && VALID_TS(act_timestamp)) {
7794 prev_ts = act_timestamp;
7795 rst_prev_ts = false;
7796 } else if (VALID_TS(prev_ts)) {
7797 bool codec_cond = (drv_ctx.timestamp_adjust)?
7798 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
7799 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
7800 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
7801 if (frm_int > 0 && codec_cond) {
7802 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
7803 act_timestamp = prev_ts + frm_int;
7804 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
7805 prev_ts = act_timestamp;
7806 } else
7807 set_frame_rate(act_timestamp);
7808 } else if (frm_int > 0) // In this case the frame rate was set along
7809 { // with the port definition, start ts with 0
7810 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
7811 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007812 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007813}
7814
7815void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
7816{
Arun Menon906de572013-06-18 17:01:40 -07007817 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
7818 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05307819 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07007820 OMX_U32 frame_rate = 0;
7821 int consumed_len = 0;
7822 OMX_U32 num_MB_in_frame;
7823 OMX_U32 recovery_sei_flags = 1;
7824 int enable = 0;
7825 OMX_U32 mbaff = 0;
7826 int buf_index = p_buf_hdr - m_out_mem_ptr;
7827 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
7828 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
7829 p_buf_hdr->nOffset;
7830 if (!drv_ctx.extradata_info.uaddr) {
7831 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007832 }
Arun Menon906de572013-06-18 17:01:40 -07007833 p_extra = (OMX_OTHER_EXTRADATATYPE *)
7834 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
7835 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
7836 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
7837 p_extra = NULL;
7838 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
7839 if (data) {
7840 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
7841 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
7842 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
7843 DEBUG_PRINT_LOW("Invalid extra data size");
7844 break;
7845 }
7846 switch ((unsigned long)data->eType) {
7847 case EXTRADATA_INTERLACE_VIDEO:
7848 struct msm_vidc_interlace_payload *payload;
7849 payload = (struct msm_vidc_interlace_payload *)data->data;
7850 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
7851 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
7852 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
7853 else {
7854 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
7855 enable = 1;
7856 }
7857 if (m_enable_android_native_buffers)
7858 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
7859 PP_PARAM_INTERLACED, (void*)&enable);
7860 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
7861 append_interlace_extradata(p_extra, payload->format);
7862 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
7863 }
7864 break;
7865 case EXTRADATA_FRAME_RATE:
7866 struct msm_vidc_framerate_payload *frame_rate_payload;
7867 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
7868 frame_rate = frame_rate_payload->frame_rate;
7869 break;
7870 case EXTRADATA_TIMESTAMP:
7871 struct msm_vidc_ts_payload *time_stamp_payload;
7872 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05307873 time_stamp = time_stamp_payload->timestamp_lo;
7874 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
7875 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07007876 break;
7877 case EXTRADATA_NUM_CONCEALED_MB:
7878 struct msm_vidc_concealmb_payload *conceal_mb_payload;
7879 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
7880 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
7881 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
7882 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
7883 break;
7884 case EXTRADATA_INDEX:
7885 int *etype;
7886 etype = (int *)(data->data);
7887 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
7888 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
7889 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
7890 if (aspect_ratio_payload) {
7891 ((struct vdec_output_frameinfo *)
7892 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
7893 ((struct vdec_output_frameinfo *)
7894 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
7895 }
7896 }
7897 break;
7898 case EXTRADATA_RECOVERY_POINT_SEI:
7899 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
7900 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
7901 recovery_sei_flags = recovery_sei_payload->flags;
7902 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
7903 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7904 DEBUG_PRINT_HIGH("\n");
7905 DEBUG_PRINT_HIGH("***************************************************\n");
7906 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
7907 DEBUG_PRINT_HIGH("***************************************************\n");
7908 }
7909 break;
7910 case EXTRADATA_PANSCAN_WINDOW:
7911 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
7912 break;
7913 case EXTRADATA_MPEG2_SEQDISP:
7914 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
7915 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
7916 if (seqdisp_payload) {
7917 m_disp_hor_size = seqdisp_payload->disp_width;
7918 m_disp_vert_size = seqdisp_payload->disp_height;
7919 }
7920 break;
7921 default:
7922 goto unrecognized_extradata;
7923 }
7924 consumed_len += data->nSize;
7925 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
7926 }
7927 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
7928 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
7929 append_frame_info_extradata(p_extra,
7930 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05307931 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07007932 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
7933 }
7934 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007935unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07007936 if (!secure_mode && client_extradata)
7937 append_terminator_extradata(p_extra);
7938 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007939}
7940
Vinay Kalia9c00cae2012-12-06 16:08:20 -08007941OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07007942 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007943{
Arun Menon906de572013-06-18 17:01:40 -07007944 OMX_ERRORTYPE ret = OMX_ErrorNone;
7945 struct v4l2_control control;
7946 if (m_state != OMX_StateLoaded) {
7947 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
7948 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08007949 }
Arun Menon906de572013-06-18 17:01:40 -07007950 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
7951 client_extradata, requested_extradata, enable, is_internal);
7952
7953 if (!is_internal) {
7954 if (enable)
7955 client_extradata |= requested_extradata;
7956 else
7957 client_extradata = client_extradata & ~requested_extradata;
7958 }
7959
7960 if (enable) {
7961 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
7962 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7963 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
7964 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7965 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
7966 " Quality of interlaced clips might be impacted.\n");
7967 }
7968 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
7969 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7970 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
7971 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7972 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
7973 }
7974 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7975 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
7976 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7977 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
7978 }
7979 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7980 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
7981 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7982 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
7983 }
7984 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7985 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
7986 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7987 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7988 }
7989 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7990 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
7991 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7992 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7993 }
7994 if (output_capability == V4L2_PIX_FMT_MPEG2) {
7995 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7996 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
7997 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7998 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7999 }
8000 }
8001 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
8002 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8003 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8004 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8005 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8006 }
8007 }
8008 }
8009 ret = get_buffer_req(&drv_ctx.op_buf);
8010 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008011}
8012
8013OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8014{
Arun Menon906de572013-06-18 17:01:40 -07008015 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8016 OMX_U8 *data_ptr = extra->data, data = 0;
8017 while (byte_count < extra->nDataSize) {
8018 data = *data_ptr;
8019 while (data) {
8020 num_MB += (data&0x01);
8021 data >>= 1;
8022 }
8023 data_ptr++;
8024 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008025 }
Arun Menon906de572013-06-18 17:01:40 -07008026 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8027 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8028 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008029}
8030
8031void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8032{
Arun Menon906de572013-06-18 17:01:40 -07008033 if (!m_debug_extradata)
8034 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008035
8036 DEBUG_PRINT_HIGH(
Arun Menon906de572013-06-18 17:01:40 -07008037 "============== Extra Data ==============\n"
8038 " Size: %lu \n"
8039 " Version: %lu \n"
8040 " PortIndex: %lu \n"
8041 " Type: %x \n"
8042 " DataSize: %lu \n",
8043 extra->nSize, extra->nVersion.nVersion,
8044 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008045
Arun Menon906de572013-06-18 17:01:40 -07008046 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8047 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8048 DEBUG_PRINT_HIGH(
8049 "------ Interlace Format ------\n"
8050 " Size: %lu \n"
8051 " Version: %lu \n"
8052 " PortIndex: %lu \n"
8053 " Is Interlace Format: %d \n"
8054 " Interlace Formats: %lu \n"
8055 "=========== End of Interlace ===========\n",
8056 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8057 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8058 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8059 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8060
8061 DEBUG_PRINT_HIGH(
8062 "-------- Frame Format --------\n"
8063 " Picture Type: %d \n"
8064 " Interlace Type: %d \n"
8065 " Pan Scan Total Frame Num: %lu \n"
8066 " Concealed Macro Blocks: %lu \n"
8067 " frame rate: %lu \n"
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05308068 " Time Stamp: %llu \n"
Arun Menon906de572013-06-18 17:01:40 -07008069 " Aspect Ratio X: %lu \n"
8070 " Aspect Ratio Y: %lu \n",
8071 fminfo->ePicType,
8072 fminfo->interlaceType,
8073 fminfo->panScan.numWindows,
8074 fminfo->nConcealedMacroblocks,
8075 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308076 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008077 fminfo->aspectRatio.aspectRatioX,
8078 fminfo->aspectRatio.aspectRatioY);
8079
8080 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8081 DEBUG_PRINT_HIGH(
8082 "------------------------------\n"
8083 " Pan Scan Frame Num: %lu \n"
8084 " Rectangle x: %ld \n"
8085 " Rectangle y: %ld \n"
8086 " Rectangle dx: %ld \n"
8087 " Rectangle dy: %ld \n",
8088 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8089 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8090 }
8091
8092 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8093 } else if (extra->eType == OMX_ExtraDataNone) {
8094 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8095 } else {
8096 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008097 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008098}
8099
8100void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008101 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008102{
Arun Menon906de572013-06-18 17:01:40 -07008103 OMX_STREAMINTERLACEFORMAT *interlace_format;
8104 OMX_U32 mbaff = 0;
8105 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8106 return;
8107 }
8108 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8109 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8110 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8111 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8112 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8113 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8114 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8115 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8116 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8117 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8118 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8119 interlace_format->bInterlaceFormat = OMX_FALSE;
8120 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8121 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8122 } else {
8123 interlace_format->bInterlaceFormat = OMX_TRUE;
8124 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8125 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8126 }
8127 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008128}
8129
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008130void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008131 struct vdec_aspectratioinfo *aspect_ratio_info,
8132 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008133{
Arun Menon906de572013-06-18 17:01:40 -07008134 m_extradata = frame_info;
8135 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8136 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308137 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008138 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008139}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008140
8141void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008142 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308143 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008144 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008145{
Arun Menon906de572013-06-18 17:01:40 -07008146 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8147 struct msm_vidc_panscan_window *panscan_window;
8148 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008149 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008150 }
Arun Menon906de572013-06-18 17:01:40 -07008151 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8152 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8153 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8154 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8155 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8156 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8157 switch (picture_type) {
8158 case PICTURE_TYPE_I:
8159 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8160 break;
8161 case PICTURE_TYPE_P:
8162 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8163 break;
8164 case PICTURE_TYPE_B:
8165 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8166 break;
8167 default:
8168 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8169 }
8170 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8171 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8172 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8173 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8174 else
8175 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8176 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8177 frame_info->nConcealedMacroblocks = num_conceal_mb;
8178 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308179 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008180 frame_info->panScan.numWindows = 0;
8181 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8182 if (m_disp_hor_size && m_disp_vert_size) {
8183 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8184 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8185 }
8186 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008187
Arun Menon906de572013-06-18 17:01:40 -07008188 if (panscan_payload) {
8189 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8190 panscan_window = &panscan_payload->wnd[0];
8191 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8192 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8193 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8194 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8195 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8196 panscan_window++;
8197 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008198 }
Arun Menon906de572013-06-18 17:01:40 -07008199 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8200 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008201}
8202
8203void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8204{
Arun Menon906de572013-06-18 17:01:40 -07008205 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8206 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8207 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8208 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8209 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8210 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8211 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8212 *portDefn = m_port_def;
8213 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8214 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
8215 portDefn->format.video.nFrameWidth,
8216 portDefn->format.video.nStride,
8217 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008218}
8219
8220void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8221{
Arun Menon906de572013-06-18 17:01:40 -07008222 if (!client_extradata) {
8223 return;
8224 }
8225 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8226 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8227 extra->eType = OMX_ExtraDataNone;
8228 extra->nDataSize = 0;
8229 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008230
Arun Menon906de572013-06-18 17:01:40 -07008231 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008232}
8233
8234OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8235{
Arun Menon906de572013-06-18 17:01:40 -07008236 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8237 if (index >= drv_ctx.ip_buf.actualcount) {
8238 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8239 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008240 }
Arun Menon906de572013-06-18 17:01:40 -07008241 if (m_desc_buffer_ptr == NULL) {
8242 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8243 calloc( (sizeof(desc_buffer_hdr)),
8244 drv_ctx.ip_buf.actualcount);
8245 if (m_desc_buffer_ptr == NULL) {
8246 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8247 return OMX_ErrorInsufficientResources;
8248 }
8249 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008250
Arun Menon906de572013-06-18 17:01:40 -07008251 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8252 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
8253 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8254 return OMX_ErrorInsufficientResources;
8255 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008256
Arun Menon906de572013-06-18 17:01:40 -07008257 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008258}
8259
8260void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8261{
Arun Menon906de572013-06-18 17:01:40 -07008262 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8263 if (m_demux_entries < 8192) {
8264 m_demux_offsets[m_demux_entries++] = address_offset;
8265 }
8266 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008267}
8268
8269void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8270{
Arun Menon906de572013-06-18 17:01:40 -07008271 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8272 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8273 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008274
Arun Menon906de572013-06-18 17:01:40 -07008275 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008276
Arun Menon906de572013-06-18 17:01:40 -07008277 while (index < bytes_to_parse) {
8278 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8279 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8280 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8281 (buf[index+2] == 0x01)) ) {
8282 //Found start code, insert address offset
8283 insert_demux_addr_offset(index);
8284 if (buf[index+2] == 0x01) // 3 byte start code
8285 index += 3;
8286 else //4 byte start code
8287 index += 4;
8288 } else
8289 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008290 }
Arun Menon906de572013-06-18 17:01:40 -07008291 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8292 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008293}
8294
8295OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8296{
Arun Menon906de572013-06-18 17:01:40 -07008297 //fix this, handle 3 byte start code, vc1 terminator entry
8298 OMX_U8 *p_demux_data = NULL;
8299 OMX_U32 desc_data = 0;
8300 OMX_U32 start_addr = 0;
8301 OMX_U32 nal_size = 0;
8302 OMX_U32 suffix_byte = 0;
8303 OMX_U32 demux_index = 0;
8304 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008305
Arun Menon906de572013-06-18 17:01:40 -07008306 if (m_desc_buffer_ptr == NULL) {
8307 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8308 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008309 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008310
Arun Menon906de572013-06-18 17:01:40 -07008311 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8312 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8313 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8314 return OMX_ErrorBadParameter;
8315 }
8316
8317 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8318
8319 if ( ((OMX_U8*)p_demux_data == NULL) ||
8320 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8321 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8322 return OMX_ErrorBadParameter;
8323 } else {
8324 for (; demux_index < m_demux_entries; demux_index++) {
8325 desc_data = 0;
8326 start_addr = m_demux_offsets[demux_index];
8327 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8328 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8329 } else {
8330 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8331 }
8332 if (demux_index < (m_demux_entries - 1)) {
8333 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8334 } else {
8335 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8336 }
8337 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8338 (void *)start_addr,
8339 suffix_byte,
8340 nal_size,
8341 demux_index);
8342 desc_data = (start_addr >> 3) << 1;
8343 desc_data |= (start_addr & 7) << 21;
8344 desc_data |= suffix_byte << 24;
8345
8346 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8347 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8348 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8349 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8350
8351 p_demux_data += 16;
8352 }
8353 if (codec_type_parse == CODEC_TYPE_VC1) {
8354 DEBUG_PRINT_LOW("VC1 terminator entry");
8355 desc_data = 0;
8356 desc_data = 0x82 << 24;
8357 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8358 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8359 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8360 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8361 p_demux_data += 16;
8362 m_demux_entries++;
8363 }
8364 //Add zero word to indicate end of descriptors
8365 memset(p_demux_data, 0, sizeof(OMX_U32));
8366
8367 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8368 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8369 }
8370 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8371 m_demux_entries = 0;
8372 DEBUG_PRINT_LOW("Demux table complete!");
8373 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008374}
8375
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008376OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008377{
Arun Menon906de572013-06-18 17:01:40 -07008378 OMX_ERRORTYPE err = OMX_ErrorNone;
8379 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8380 if (iDivXDrmDecrypt) {
8381 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8382 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008383 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008384 delete iDivXDrmDecrypt;
8385 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008386 }
8387 } else {
8388 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
8389 err = OMX_ErrorUndefined;
8390 }
8391 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008392}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008393
Vinay Kaliada4f4422013-01-09 10:45:03 -08008394omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8395{
Arun Menon906de572013-06-18 17:01:40 -07008396 enabled = false;
8397 omx = NULL;
8398 init_members();
8399 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008400}
8401
8402void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8403{
Arun Menon906de572013-06-18 17:01:40 -07008404 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008405}
8406
Arun Menon906de572013-06-18 17:01:40 -07008407void omx_vdec::allocate_color_convert_buf::init_members()
8408{
8409 allocated_count = 0;
8410 buffer_size_req = 0;
8411 buffer_alignment_req = 0;
8412 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8413 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8414 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8415 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008416#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008417 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008418#endif
Arun Menon906de572013-06-18 17:01:40 -07008419 for (int i = 0; i < MAX_COUNT; i++)
8420 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008421}
8422
Arun Menon906de572013-06-18 17:01:40 -07008423omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8424{
8425 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008426}
8427
8428bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8429{
Arun Menon906de572013-06-18 17:01:40 -07008430 bool status = true;
8431 unsigned int src_size = 0, destination_size = 0;
8432 OMX_COLOR_FORMATTYPE drv_color_format;
8433 if (!omx) {
8434 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8435 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008436 }
Arun Menon906de572013-06-18 17:01:40 -07008437 if (!enabled) {
8438 DEBUG_PRINT_HIGH("\n No color conversion required");
8439 return status;
8440 }
8441 pthread_mutex_lock(&omx->c_lock);
8442 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8443 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8444 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
8445 status = false;
8446 goto fail_update_buf_req;
8447 }
8448 c2d.close();
8449 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8450 omx->drv_ctx.video_resolution.frame_width,
8451 NV12_128m,YCbCr420P);
8452 if (status) {
8453 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8454 if (status)
8455 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8456 }
8457 if (status) {
8458 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8459 !destination_size) {
8460 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
8461 "driver size %d destination size %d",
8462 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8463 status = false;
8464 c2d.close();
8465 buffer_size_req = 0;
8466 } else {
8467 buffer_size_req = destination_size;
8468 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8469 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8470 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8471 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8472 }
8473 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008474fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008475 pthread_mutex_unlock(&omx->c_lock);
8476 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008477}
8478
8479bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008480 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008481{
Arun Menon906de572013-06-18 17:01:40 -07008482 bool status = true;
8483 OMX_COLOR_FORMATTYPE drv_color_format;
8484 if (!omx) {
8485 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8486 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008487 }
Arun Menon906de572013-06-18 17:01:40 -07008488 pthread_mutex_lock(&omx->c_lock);
8489 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8490 drv_color_format = (OMX_COLOR_FORMATTYPE)
8491 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8492 else {
8493 DEBUG_PRINT_ERROR("\n Incorrect color format");
8494 status = false;
8495 }
8496 if (status && (drv_color_format != dest_color_format)) {
8497 DEBUG_PRINT_LOW("Enabling C2D\n");
8498 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
8499 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
8500 status = false;
8501 } else {
8502 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8503 if (enabled)
8504 c2d.destroy();
8505 enabled = false;
8506 if (!c2d.init()) {
8507 DEBUG_PRINT_ERROR("\n open failed for c2d");
8508 status = false;
8509 } else
8510 enabled = true;
8511 }
8512 } else {
8513 if (enabled)
8514 c2d.destroy();
8515 enabled = false;
8516 }
8517 pthread_mutex_unlock(&omx->c_lock);
8518 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008519}
8520
8521OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8522{
Arun Menon906de572013-06-18 17:01:40 -07008523 if (!omx) {
8524 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8525 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008526 }
Arun Menon906de572013-06-18 17:01:40 -07008527 if (!enabled)
8528 return omx->m_out_mem_ptr;
8529 return m_out_mem_ptr_client;
8530}
8531
8532 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
8533(OMX_BUFFERHEADERTYPE *bufadd)
8534{
8535 if (!omx) {
8536 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8537 return NULL;
8538 }
8539 if (!enabled)
8540 return bufadd;
8541
8542 unsigned index = 0;
8543 index = bufadd - omx->m_out_mem_ptr;
8544 if (index < omx->drv_ctx.op_buf.actualcount) {
8545 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
8546 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
8547 bool status;
8548 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
8549 pthread_mutex_lock(&omx->c_lock);
8550 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
8551 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
8552 pmem_baseaddress[index], pmem_baseaddress[index]);
8553 pthread_mutex_unlock(&omx->c_lock);
8554 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
8555 if (!status) {
8556 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
8557 m_out_mem_ptr_client[index].nFilledLen = 0;
8558 return &m_out_mem_ptr_client[index];
8559 }
8560 } else
8561 m_out_mem_ptr_client[index].nFilledLen = 0;
8562 return &m_out_mem_ptr_client[index];
8563 }
8564 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
8565 return NULL;
8566}
8567
8568 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
8569(OMX_BUFFERHEADERTYPE *bufadd)
8570{
8571 if (!omx) {
8572 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8573 return NULL;
8574 }
8575 if (!enabled)
8576 return bufadd;
8577 unsigned index = 0;
8578 index = bufadd - m_out_mem_ptr_client;
8579 if (index < omx->drv_ctx.op_buf.actualcount) {
8580 return &omx->m_out_mem_ptr[index];
8581 }
8582 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
8583 return NULL;
8584}
8585 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
8586(unsigned int &buffer_size)
8587{
8588 bool status = true;
8589 pthread_mutex_lock(&omx->c_lock);
8590 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008591 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07008592 else {
8593 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
8594 DEBUG_PRINT_ERROR("\n Get buffer size failed");
8595 status = false;
8596 goto fail_get_buffer_size;
8597 }
8598 }
8599 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
8600 buffer_size = omx->drv_ctx.op_buf.buffer_size;
8601 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8602 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008603fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07008604 pthread_mutex_unlock(&omx->c_lock);
8605 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008606}
8607OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07008608 OMX_BUFFERHEADERTYPE *bufhdr)
8609{
8610 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008611
Arun Menon906de572013-06-18 17:01:40 -07008612 if (!enabled)
8613 return omx->free_output_buffer(bufhdr);
8614 if (enabled && omx->is_component_secure())
8615 return OMX_ErrorNone;
8616 if (!allocated_count || !bufhdr) {
8617 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
8618 return OMX_ErrorBadParameter;
8619 }
8620 index = bufhdr - m_out_mem_ptr_client;
8621 if (index >= omx->drv_ctx.op_buf.actualcount) {
8622 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
8623 return OMX_ErrorBadParameter;
8624 }
8625 if (pmem_fd[index] > 0) {
8626 munmap(pmem_baseaddress[index], buffer_size_req);
8627 close(pmem_fd[index]);
8628 }
8629 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008630#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008631 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008632#endif
Arun Menon906de572013-06-18 17:01:40 -07008633 m_heap_ptr[index].video_heap_ptr = NULL;
8634 if (allocated_count > 0)
8635 allocated_count--;
8636 else
8637 allocated_count = 0;
8638 if (!allocated_count) {
8639 pthread_mutex_lock(&omx->c_lock);
8640 c2d.close();
8641 init_members();
8642 pthread_mutex_unlock(&omx->c_lock);
8643 }
8644 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008645}
8646
8647OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07008648 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008649{
Arun Menon906de572013-06-18 17:01:40 -07008650 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8651 if (!enabled) {
8652 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
8653 return eRet;
8654 }
8655 if (enabled && omx->is_component_secure()) {
8656 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
8657 omx->is_component_secure());
8658 return OMX_ErrorUnsupportedSetting;
8659 }
8660 if (!bufferHdr || bytes > buffer_size_req) {
8661 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
8662 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
8663 buffer_size_req,bytes);
8664 return OMX_ErrorBadParameter;
8665 }
8666 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
8667 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
8668 return OMX_ErrorInsufficientResources;
8669 }
8670 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
8671 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
8672 port,appData,omx->drv_ctx.op_buf.buffer_size);
8673 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
8674 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
8675 return eRet;
8676 }
8677 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
8678 omx->drv_ctx.op_buf.actualcount) {
8679 DEBUG_PRINT_ERROR("\n Invalid header index %d",
8680 (temp_bufferHdr - omx->m_out_mem_ptr));
8681 return OMX_ErrorUndefined;
8682 }
8683 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008684#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008685 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
8686 buffer_size_req,buffer_alignment_req,
8687 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
8688 0);
8689 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
8690 if (op_buf_ion_info[i].ion_device_fd < 0) {
8691 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
8692 return OMX_ErrorInsufficientResources;
8693 }
8694 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
8695 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008696
Arun Menon906de572013-06-18 17:01:40 -07008697 if (pmem_baseaddress[i] == MAP_FAILED) {
8698 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
8699 close(pmem_fd[i]);
8700 omx->free_ion_memory(&op_buf_ion_info[i]);
8701 return OMX_ErrorInsufficientResources;
8702 }
8703 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
8704 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
8705 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008706#endif
Arun Menon906de572013-06-18 17:01:40 -07008707 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
8708 m_pmem_info_client[i].offset = 0;
8709 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
8710 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8711 m_platform_list_client[i].nEntries = 1;
8712 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
8713 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
8714 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
8715 m_out_mem_ptr_client[i].nFilledLen = 0;
8716 m_out_mem_ptr_client[i].nFlags = 0;
8717 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8718 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
8719 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
8720 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
8721 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
8722 m_out_mem_ptr_client[i].pAppPrivate = appData;
8723 *bufferHdr = &m_out_mem_ptr_client[i];
8724 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
8725 allocated_count++;
8726 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008727}
8728
8729bool omx_vdec::is_component_secure()
8730{
Arun Menon906de572013-06-18 17:01:40 -07008731 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008732}
8733
8734bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
8735{
Arun Menon906de572013-06-18 17:01:40 -07008736 bool status = true;
8737 if (!enabled) {
8738 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8739 dest_color_format = (OMX_COLOR_FORMATTYPE)
8740 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8741 else
8742 status = false;
8743 } else {
8744 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8745 status = false;
8746 } else
8747 dest_color_format = OMX_COLOR_FormatYUV420Planar;
8748 }
8749 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008750}