blob: 998bb6c37cbb2ee17f0e653ad8bda6ac35c7db3a [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_
Arun Menon906de572013-06-18 17:01:40 -07001387 char platform_name[64];
1388 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 }
3355 default: {
3356 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3357 eRet = OMX_ErrorUnsupportedIndex;
3358 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003359 }
Arun Menon906de572013-06-18 17:01:40 -07003360 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003361}
3362
3363/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003364 FUNCTION
3365 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003366
Arun Menon906de572013-06-18 17:01:40 -07003367 DESCRIPTION
3368 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003369
Arun Menon906de572013-06-18 17:01:40 -07003370 PARAMETERS
3371 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003372
Arun Menon906de572013-06-18 17:01:40 -07003373 RETURN VALUE
3374 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003375
Arun Menon906de572013-06-18 17:01:40 -07003376 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003377OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003378 OMX_IN OMX_INDEXTYPE configIndex,
3379 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003380{
Arun Menon906de572013-06-18 17:01:40 -07003381 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003382
Arun Menon906de572013-06-18 17:01:40 -07003383 if (m_state == OMX_StateInvalid) {
3384 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003385 return OMX_ErrorInvalidState;
3386 }
Arun Menon906de572013-06-18 17:01:40 -07003387
3388 switch ((unsigned long)configIndex) {
3389 case OMX_QcomIndexConfigInterlaced: {
3390 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3391 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3392 if (configFmt->nPortIndex == 1) {
3393 if (configFmt->nIndex == 0) {
3394 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3395 } else if (configFmt->nIndex == 1) {
3396 configFmt->eInterlaceType =
3397 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3398 } else if (configFmt->nIndex == 2) {
3399 configFmt->eInterlaceType =
3400 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3401 } else {
3402 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3403 " NoMore Interlaced formats\n");
3404 eRet = OMX_ErrorNoMore;
3405 }
3406
3407 } else {
3408 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3409 (int)configFmt->nPortIndex);
3410 eRet = OMX_ErrorBadPortIndex;
3411 }
3412 break;
3413 }
3414 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3415 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3416 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3417 decoderinstances->nNumOfInstances = 16;
3418 /*TODO: How to handle this case */
3419 break;
3420 }
3421 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3422 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3423 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3424 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3425 h264_parser->get_frame_pack_data(configFmt);
3426 } else {
3427 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3428 }
3429 break;
3430 }
3431 case OMX_IndexConfigCommonOutputCrop: {
3432 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3433 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3434 break;
3435 }
3436 default: {
3437 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3438 eRet = OMX_ErrorBadParameter;
3439 }
3440
Shalaj Jain273b3e02012-06-22 19:08:03 -07003441 }
Arun Menon906de572013-06-18 17:01:40 -07003442
3443 return eRet;
3444}
3445
3446/* ======================================================================
3447 FUNCTION
3448 omx_vdec::SetConfig
3449
3450 DESCRIPTION
3451 OMX Set Config method implementation
3452
3453 PARAMETERS
3454 <TBD>.
3455
3456 RETURN VALUE
3457 OMX Error None if successful.
3458 ========================================================================== */
3459OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3460 OMX_IN OMX_INDEXTYPE configIndex,
3461 OMX_IN OMX_PTR configData)
3462{
3463 if (m_state == OMX_StateInvalid) {
3464 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3465 return OMX_ErrorInvalidState;
3466 }
3467
3468 OMX_ERRORTYPE ret = OMX_ErrorNone;
3469 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3470
3471 DEBUG_PRINT_LOW("\n Set Config Called");
3472
3473 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3474 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3475 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3476 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
3477 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3478 OMX_U32 extra_size;
3479 // Parsing done here for the AVC atom is definitely not generic
3480 // Currently this piece of code is working, but certainly
3481 // not tested with all .mp4 files.
3482 // Incase of failure, we might need to revisit this
3483 // for a generic piece of code.
3484
3485 // Retrieve size of NAL length field
3486 // byte #4 contains the size of NAL lenght field
3487 nal_length = (config->pData[4] & 0x03) + 1;
3488
3489 extra_size = 0;
3490 if (nal_length > 2) {
3491 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3492 extra_size = (nal_length - 2) * 2;
3493 }
3494
3495 // SPS starts from byte #6
3496 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3497 OMX_U8 *pDestBuf;
3498 m_vendor_config.nPortIndex = config->nPortIndex;
3499
3500 // minus 6 --> SPS starts from byte #6
3501 // minus 1 --> picture param set byte to be ignored from avcatom
3502 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3503 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3504 OMX_U32 len;
3505 OMX_U8 index = 0;
3506 // case where SPS+PPS is sent as part of set_config
3507 pDestBuf = m_vendor_config.pData;
3508
3509 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
3510 m_vendor_config.nPortIndex,
3511 m_vendor_config.nDataSize,
3512 m_vendor_config.pData);
3513 while (index < 2) {
3514 uint8 *psize;
3515 len = *pSrcBuf;
3516 len = len << 8;
3517 len |= *(pSrcBuf + 1);
3518 psize = (uint8 *) & len;
3519 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3520 for (unsigned int i = 0; i < nal_length; i++) {
3521 pDestBuf[i] = psize[nal_length - 1 - i];
3522 }
3523 //memcpy(pDestBuf,pSrcBuf,(len+2));
3524 pDestBuf += len + nal_length;
3525 pSrcBuf += len + 2;
3526 index++;
3527 pSrcBuf++; // skip picture param set
3528 len = 0;
3529 }
3530 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3531 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3532 m_vendor_config.nPortIndex = config->nPortIndex;
3533 m_vendor_config.nDataSize = config->nDataSize;
3534 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3535 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3536 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3537 if (m_vendor_config.pData) {
3538 free(m_vendor_config.pData);
3539 m_vendor_config.pData = NULL;
3540 m_vendor_config.nDataSize = 0;
3541 }
3542
3543 if (((*((OMX_U32 *) config->pData)) &
3544 VC1_SP_MP_START_CODE_MASK) ==
3545 VC1_SP_MP_START_CODE) {
3546 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3547 m_vendor_config.nPortIndex = config->nPortIndex;
3548 m_vendor_config.nDataSize = config->nDataSize;
3549 m_vendor_config.pData =
3550 (OMX_U8 *) malloc(config->nDataSize);
3551 memcpy(m_vendor_config.pData, config->pData,
3552 config->nDataSize);
3553 m_vc1_profile = VC1_SP_MP_RCV;
3554 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
3555 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3556 m_vendor_config.nPortIndex = config->nPortIndex;
3557 m_vendor_config.nDataSize = config->nDataSize;
3558 m_vendor_config.pData =
3559 (OMX_U8 *) malloc((config->nDataSize));
3560 memcpy(m_vendor_config.pData, config->pData,
3561 config->nDataSize);
3562 m_vc1_profile = VC1_AP;
3563 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
3564 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3565 m_vendor_config.nPortIndex = config->nPortIndex;
3566 m_vendor_config.nDataSize = config->nDataSize;
3567 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3568 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3569 m_vc1_profile = VC1_SP_MP_RCV;
3570 } else {
3571 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3572 }
3573 }
3574 return ret;
3575 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3576 struct v4l2_control temp;
3577 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3578
3579 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3580 switch (pNal->nNaluBytes) {
3581 case 0:
3582 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3583 break;
3584 case 2:
3585 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3586 break;
3587 case 4:
3588 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3589 break;
3590 default:
3591 return OMX_ErrorUnsupportedSetting;
3592 }
3593
3594 if (!arbitrary_bytes) {
3595 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3596 * with start code, so only need to notify driver in frame by frame mode */
3597 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3598 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3599 return OMX_ErrorHardware;
3600 }
3601 }
3602
3603 nal_length = pNal->nNaluBytes;
3604 m_frame_parser.init_nal_length(nal_length);
3605
3606 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
3607 return ret;
3608 } else if (configIndex == OMX_IndexVendorVideoFrameRate) {
3609 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
3610 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps);
3611
3612 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3613 if (config->bEnabled) {
3614 if ((config->nFps >> 16) > 0) {
3615 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d",
3616 config->nFps >> 16);
3617 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3618 drv_ctx.frame_rate.fps_denominator);
3619
3620 if (!drv_ctx.frame_rate.fps_numerator) {
3621 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3622 drv_ctx.frame_rate.fps_numerator = 30;
3623 }
3624
3625 if (drv_ctx.frame_rate.fps_denominator) {
3626 drv_ctx.frame_rate.fps_numerator = (int)
3627 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3628 }
3629
3630 drv_ctx.frame_rate.fps_denominator = 1;
3631 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3632 drv_ctx.frame_rate.fps_numerator;
3633
3634 struct v4l2_outputparm oparm;
3635 /*XXX: we're providing timing info as seconds per frame rather than frames
3636 * per second.*/
3637 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3638 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3639
3640 struct v4l2_streamparm sparm;
3641 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3642 sparm.parm.output = oparm;
3643 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3644 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3645 performance might be affected");
3646 ret = OMX_ErrorHardware;
3647 }
3648 client_set_fps = true;
3649 } else {
3650 DEBUG_PRINT_ERROR("Frame rate not supported.");
3651 ret = OMX_ErrorUnsupportedSetting;
3652 }
3653 } else {
3654 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3655 client_set_fps = false;
3656 }
3657 } else {
3658 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3659 (int)config->nPortIndex);
3660 ret = OMX_ErrorBadPortIndex;
3661 }
3662
3663 return ret;
3664 }
3665
3666 return OMX_ErrorNotImplemented;
3667}
3668
3669/* ======================================================================
3670 FUNCTION
3671 omx_vdec::GetExtensionIndex
3672
3673 DESCRIPTION
3674 OMX GetExtensionIndex method implementaion. <TBD>
3675
3676 PARAMETERS
3677 <TBD>.
3678
3679 RETURN VALUE
3680 OMX Error None if everything successful.
3681
3682 ========================================================================== */
3683OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3684 OMX_IN OMX_STRING paramName,
3685 OMX_OUT OMX_INDEXTYPE* indexType)
3686{
3687 if (m_state == OMX_StateInvalid) {
3688 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3689 return OMX_ErrorInvalidState;
3690 } else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3691 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3692 } else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003693 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3694 }
3695#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003696 else if (!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003697 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Arun Menon906de572013-06-18 17:01:40 -07003698 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003699 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Arun Menon906de572013-06-18 17:01:40 -07003700 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003701 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3702 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Arun Menon906de572013-06-18 17:01:40 -07003703 } else if (!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003704 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3705 }
3706#endif
Arun Menon906de572013-06-18 17:01:40 -07003707 else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003708 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3709 return OMX_ErrorNotImplemented;
3710 }
3711 return OMX_ErrorNone;
3712}
3713
3714/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003715 FUNCTION
3716 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07003717
Arun Menon906de572013-06-18 17:01:40 -07003718 DESCRIPTION
3719 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003720
Arun Menon906de572013-06-18 17:01:40 -07003721 PARAMETERS
3722 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003723
Arun Menon906de572013-06-18 17:01:40 -07003724 RETURN VALUE
3725 Error None if everything is successful.
3726 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003727OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003728 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003729{
Arun Menon906de572013-06-18 17:01:40 -07003730 *state = m_state;
3731 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
3732 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003733}
3734
3735/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003736 FUNCTION
3737 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07003738
Arun Menon906de572013-06-18 17:01:40 -07003739 DESCRIPTION
3740 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003741
Arun Menon906de572013-06-18 17:01:40 -07003742 PARAMETERS
3743 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003744
Arun Menon906de572013-06-18 17:01:40 -07003745 RETURN VALUE
3746 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003747
Arun Menon906de572013-06-18 17:01:40 -07003748 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003749OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003750 OMX_IN OMX_U32 port,
3751 OMX_IN OMX_HANDLETYPE peerComponent,
3752 OMX_IN OMX_U32 peerPort,
3753 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003754{
Arun Menon906de572013-06-18 17:01:40 -07003755 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3756 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003757}
3758
3759/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003760 FUNCTION
3761 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07003762
Arun Menon906de572013-06-18 17:01:40 -07003763 DESCRIPTION
3764 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07003765
Arun Menon906de572013-06-18 17:01:40 -07003766 PARAMETERS
3767 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003768
Arun Menon906de572013-06-18 17:01:40 -07003769 RETURN VALUE
3770 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07003771
Arun Menon906de572013-06-18 17:01:40 -07003772 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003773OMX_ERRORTYPE omx_vdec::allocate_extradata()
3774{
3775#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003776 if (drv_ctx.extradata_info.buffer_size) {
3777 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
3778 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3779 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3780 free_ion_memory(&drv_ctx.extradata_info.ion);
3781 }
3782 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
3783 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
3784 drv_ctx.extradata_info.size, 4096,
3785 &drv_ctx.extradata_info.ion.ion_alloc_data,
3786 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
3787 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
3788 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
3789 return OMX_ErrorInsufficientResources;
3790 }
3791 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
3792 drv_ctx.extradata_info.size,
3793 PROT_READ|PROT_WRITE, MAP_SHARED,
3794 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
3795 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
3796 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
3797 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3798 free_ion_memory(&drv_ctx.extradata_info.ion);
3799 return OMX_ErrorInsufficientResources;
3800 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003801 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003802#endif
Arun Menon906de572013-06-18 17:01:40 -07003803 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003804}
3805
Arun Menon906de572013-06-18 17:01:40 -07003806void omx_vdec::free_extradata()
3807{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003808#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003809 if (drv_ctx.extradata_info.uaddr) {
3810 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3811 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3812 free_ion_memory(&drv_ctx.extradata_info.ion);
3813 }
3814 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003815#endif
3816}
3817
Shalaj Jain273b3e02012-06-22 19:08:03 -07003818OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07003819 OMX_IN OMX_HANDLETYPE hComp,
3820 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3821 OMX_IN OMX_U32 port,
3822 OMX_IN OMX_PTR appData,
3823 OMX_IN OMX_U32 bytes,
3824 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003825{
Arun Menon906de572013-06-18 17:01:40 -07003826 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3827 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
3828 unsigned i= 0; // Temporary counter
3829 struct vdec_setbuffer_cmd setbuffers;
3830 OMX_PTR privateAppData = NULL;
3831 private_handle_t *handle = NULL;
3832 OMX_U8 *buff = buffer;
3833 struct v4l2_buffer buf;
3834 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3835 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003836
Arun Menon906de572013-06-18 17:01:40 -07003837 if (!m_out_mem_ptr) {
3838 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
3839 eRet = allocate_output_headers();
3840 if (eRet == OMX_ErrorNone)
3841 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07003842 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003843
Arun Menon906de572013-06-18 17:01:40 -07003844 if (eRet == OMX_ErrorNone) {
3845 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
3846 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
3847 break;
3848 }
3849 }
3850 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003851
Arun Menon906de572013-06-18 17:01:40 -07003852 if (i >= drv_ctx.op_buf.actualcount) {
3853 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
3854 eRet = OMX_ErrorInsufficientResources;
3855 }
3856
3857 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003858#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003859 if (m_enable_android_native_buffers) {
3860 if (m_use_android_native_buffers) {
3861 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
3862 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3863 handle = (private_handle_t *)nBuf->handle;
3864 privateAppData = params->pAppPrivate;
3865 } else {
3866 handle = (private_handle_t *)buff;
3867 privateAppData = appData;
3868 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003869
Arun Menon906de572013-06-18 17:01:40 -07003870 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
3871 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
3872 " expected %u, got %lu",
3873 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
3874 return OMX_ErrorBadParameter;
3875 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003876
Arun Menon906de572013-06-18 17:01:40 -07003877 if (!m_use_android_native_buffers) {
3878 if (!secure_mode) {
3879 buff = (OMX_U8*)mmap(0, handle->size,
3880 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3881 if (buff == MAP_FAILED) {
3882 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3883 return OMX_ErrorInsufficientResources;
3884 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003885 }
3886 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003887#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003888 native_buffer[i].nativehandle = handle;
3889 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003890#endif
Arun Menon906de572013-06-18 17:01:40 -07003891 if (!handle) {
3892 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
3893 return OMX_ErrorBadParameter;
3894 }
3895 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
3896 drv_ctx.ptr_outputbuffer[i].offset = 0;
3897 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
3898 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
3899 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
3900 } else
3901#endif
3902
3903 if (!ouput_egl_buffers && !m_use_output_pmem) {
3904#ifdef USE_ION
3905 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
3906 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
3907 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
3908 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
3909 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
3910 DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd);
3911 return OMX_ErrorInsufficientResources;
3912 }
3913 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3914 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
3915#else
3916 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3917 open (MEM_DEVICE,O_RDWR);
3918
3919 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
3920 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
3921 return OMX_ErrorInsufficientResources;
3922 }
3923
3924 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
3925 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
3926 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3927 open (MEM_DEVICE,O_RDWR);
3928 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
3929 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
3930 return OMX_ErrorInsufficientResources;
3931 }
3932 }
3933
3934 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
3935 drv_ctx.op_buf.buffer_size,
3936 drv_ctx.op_buf.alignment)) {
3937 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3938 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
3939 return OMX_ErrorInsufficientResources;
3940 }
3941#endif
3942 if (!secure_mode) {
3943 drv_ctx.ptr_outputbuffer[i].bufferaddr =
3944 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
3945 PROT_READ|PROT_WRITE, MAP_SHARED,
3946 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
3947 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
3948 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
3949#ifdef USE_ION
3950 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
3951#endif
3952 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
3953 return OMX_ErrorInsufficientResources;
3954 }
3955 }
3956 drv_ctx.ptr_outputbuffer[i].offset = 0;
3957 privateAppData = appData;
3958 } else {
3959
3960 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
3961 if (!appData || !bytes ) {
3962 if (!secure_mode && !buffer) {
3963 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
3964 return OMX_ErrorBadParameter;
3965 }
3966 }
3967
3968 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
3969 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
3970 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
3971 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
3972 !pmem_list->nEntries ||
3973 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3974 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
3975 return OMX_ErrorBadParameter;
3976 }
3977 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
3978 pmem_list->entryList->entry;
3979 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
3980 pmem_info->pmem_fd);
3981 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
3982 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
3983 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
3984 drv_ctx.ptr_outputbuffer[i].mmaped_size =
3985 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
3986 privateAppData = appData;
3987 }
3988 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
3989 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
3990
3991 *bufferHdr = (m_out_mem_ptr + i );
3992 if (secure_mode)
3993 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
3994 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
3995 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
3996 sizeof (vdec_bufferpayload));
3997
3998 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
3999 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4000 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4001
4002 buf.index = i;
4003 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4004 buf.memory = V4L2_MEMORY_USERPTR;
4005 plane[0].length = drv_ctx.op_buf.buffer_size;
4006 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4007 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4008 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4009 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4010 plane[0].data_offset = 0;
4011 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4012 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4013 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4014 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4015#ifdef USE_ION
4016 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4017#endif
4018 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4019 plane[extra_idx].data_offset = 0;
4020 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4021 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004022 return OMX_ErrorBadParameter;
4023 }
Arun Menon906de572013-06-18 17:01:40 -07004024 buf.m.planes = plane;
4025 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004026
Arun Menon906de572013-06-18 17:01:40 -07004027 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4028 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4029 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004030 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004031 }
4032
Arun Menon906de572013-06-18 17:01:40 -07004033 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4034 enum v4l2_buf_type buf_type;
4035 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4036 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4037 return OMX_ErrorInsufficientResources;
4038 } else {
4039 streaming[CAPTURE_PORT] = true;
4040 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004041 }
4042 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004043
Arun Menon906de572013-06-18 17:01:40 -07004044 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4045 if (m_enable_android_native_buffers) {
4046 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4047 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4048 } else {
4049 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004050 }
Arun Menon906de572013-06-18 17:01:40 -07004051 (*bufferHdr)->pAppPrivate = privateAppData;
4052 BITMASK_SET(&m_out_bm_count,i);
4053 }
4054 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004055}
4056
4057/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004058 FUNCTION
4059 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004060
Arun Menon906de572013-06-18 17:01:40 -07004061 DESCRIPTION
4062 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004063
Arun Menon906de572013-06-18 17:01:40 -07004064 PARAMETERS
4065 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004066
Arun Menon906de572013-06-18 17:01:40 -07004067 RETURN VALUE
4068 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004069
Arun Menon906de572013-06-18 17:01:40 -07004070 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004071OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004072 OMX_IN OMX_HANDLETYPE hComp,
4073 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4074 OMX_IN OMX_U32 port,
4075 OMX_IN OMX_PTR appData,
4076 OMX_IN OMX_U32 bytes,
4077 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004078{
Arun Menon906de572013-06-18 17:01:40 -07004079 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4080 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4081 if (!m_inp_heap_ptr)
4082 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4083 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4084 drv_ctx.ip_buf.actualcount);
4085 if (!m_phdr_pmem_ptr)
4086 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4087 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4088 drv_ctx.ip_buf.actualcount);
4089 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4090 DEBUG_PRINT_ERROR("Insufficent memory");
4091 eRet = OMX_ErrorInsufficientResources;
4092 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4093 input_use_buffer = true;
4094 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4095 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4096 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4097 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4098 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4099 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4100 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4101 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4102 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
4103 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4104 (unsigned)NULL, (unsigned)NULL)) {
4105 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4106 return OMX_ErrorInsufficientResources;
4107 }
4108 m_in_alloc_cnt++;
4109 } else {
4110 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4111 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004112 }
Arun Menon906de572013-06-18 17:01:40 -07004113 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004114}
4115
4116/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004117 FUNCTION
4118 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004119
Arun Menon906de572013-06-18 17:01:40 -07004120 DESCRIPTION
4121 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004122
Arun Menon906de572013-06-18 17:01:40 -07004123 PARAMETERS
4124 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004125
Arun Menon906de572013-06-18 17:01:40 -07004126 RETURN VALUE
4127 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004128
Arun Menon906de572013-06-18 17:01:40 -07004129 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004130OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004131 OMX_IN OMX_HANDLETYPE hComp,
4132 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4133 OMX_IN OMX_U32 port,
4134 OMX_IN OMX_PTR appData,
4135 OMX_IN OMX_U32 bytes,
4136 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004137{
Arun Menon906de572013-06-18 17:01:40 -07004138 OMX_ERRORTYPE error = OMX_ErrorNone;
4139 struct vdec_setbuffer_cmd setbuffers;
4140
4141 if (bufferHdr == NULL || bytes == 0) {
4142 if (!secure_mode && buffer == NULL) {
4143 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4144 return OMX_ErrorBadParameter;
4145 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004146 }
Arun Menon906de572013-06-18 17:01:40 -07004147 if (m_state == OMX_StateInvalid) {
4148 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4149 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004150 }
Arun Menon906de572013-06-18 17:01:40 -07004151 if (port == OMX_CORE_INPUT_PORT_INDEX)
4152 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4153 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4154 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4155 else {
4156 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4157 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004158 }
Arun Menon906de572013-06-18 17:01:40 -07004159 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4160 if (error == OMX_ErrorNone) {
4161 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4162 // Send the callback now
4163 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4164 post_event(OMX_CommandStateSet,OMX_StateIdle,
4165 OMX_COMPONENT_GENERATE_EVENT);
4166 }
4167 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4168 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4169 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4170 post_event(OMX_CommandPortEnable,
4171 OMX_CORE_INPUT_PORT_INDEX,
4172 OMX_COMPONENT_GENERATE_EVENT);
4173 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4174 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4175 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4176 post_event(OMX_CommandPortEnable,
4177 OMX_CORE_OUTPUT_PORT_INDEX,
4178 OMX_COMPONENT_GENERATE_EVENT);
4179 }
4180 }
4181 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004182}
4183
4184OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004185 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004186{
Arun Menon906de572013-06-18 17:01:40 -07004187 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4188 if (m_inp_heap_ptr[bufferindex].pBuffer)
4189 free(m_inp_heap_ptr[bufferindex].pBuffer);
4190 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4191 }
4192 if (pmem_bufferHdr)
4193 free_input_buffer(pmem_bufferHdr);
4194 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004195}
4196
4197OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4198{
Arun Menon906de572013-06-18 17:01:40 -07004199 unsigned int index = 0;
4200 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4201 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004202 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004203
Arun Menon906de572013-06-18 17:01:40 -07004204 index = bufferHdr - m_inp_mem_ptr;
4205 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4206
4207 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
4208 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4209 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4210 struct vdec_setbuffer_cmd setbuffers;
4211 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4212 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4213 sizeof (vdec_bufferpayload));
4214 if (!secure_mode) {
4215 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4216 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4217 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4218 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4219 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4220 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4221 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4222 }
4223 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4224 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4225 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4226 free(m_desc_buffer_ptr[index].buf_addr);
4227 m_desc_buffer_ptr[index].buf_addr = NULL;
4228 m_desc_buffer_ptr[index].desc_data_size = 0;
4229 }
4230#ifdef USE_ION
4231 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4232#endif
4233 }
4234 }
4235
4236 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004237}
4238
4239OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4240{
Arun Menon906de572013-06-18 17:01:40 -07004241 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004242
Arun Menon906de572013-06-18 17:01:40 -07004243 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4244 return OMX_ErrorBadParameter;
4245 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004246
Arun Menon906de572013-06-18 17:01:40 -07004247 index = bufferHdr - m_out_mem_ptr;
4248 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004249
Arun Menon906de572013-06-18 17:01:40 -07004250 if (index < drv_ctx.op_buf.actualcount
4251 && drv_ctx.ptr_outputbuffer) {
4252 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
4253 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004254
Arun Menon906de572013-06-18 17:01:40 -07004255 struct vdec_setbuffer_cmd setbuffers;
4256 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4257 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4258 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004259#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004260 if (m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004261 if (!secure_mode) {
Arun Menon906de572013-06-18 17:01:40 -07004262 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4263 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4264 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4265 }
Praveen Chavan212671f2013-04-05 20:00:42 -07004266 }
Arun Menon906de572013-06-18 17:01:40 -07004267 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4268 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004269#endif
Arun Menon906de572013-06-18 17:01:40 -07004270 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4271 if (!secure_mode) {
4272 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4273 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4274 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4275 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4276 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4277 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4278 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4279 }
4280 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4281 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004282#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004283 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004284#endif
Arun Menon906de572013-06-18 17:01:40 -07004285 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004286#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004287 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004288#endif
Arun Menon906de572013-06-18 17:01:40 -07004289 if (release_output_done()) {
4290 free_extradata();
4291 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004292 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004293
Arun Menon906de572013-06-18 17:01:40 -07004294 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004295
4296}
4297
4298OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004299 OMX_BUFFERHEADERTYPE **bufferHdr,
4300 OMX_U32 port,
4301 OMX_PTR appData,
4302 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004303{
Arun Menon906de572013-06-18 17:01:40 -07004304 OMX_BUFFERHEADERTYPE *input = NULL;
4305 unsigned char *buf_addr = NULL;
4306 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4307 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004308
Arun Menon906de572013-06-18 17:01:40 -07004309 /* Sanity Check*/
4310 if (bufferHdr == NULL) {
4311 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004312 }
4313
Arun Menon906de572013-06-18 17:01:40 -07004314 if (m_inp_heap_ptr == NULL) {
Leena Winterrowd3e959242013-08-12 18:26:57 -07004315 m_frame_parser.reset();
Arun Menon906de572013-06-18 17:01:40 -07004316 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4317 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4318 drv_ctx.ip_buf.actualcount);
4319 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4320 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4321 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004322
Arun Menon906de572013-06-18 17:01:40 -07004323 if (m_inp_heap_ptr == NULL) {
4324 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4325 return OMX_ErrorInsufficientResources;
4326 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004327 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004328
Arun Menon906de572013-06-18 17:01:40 -07004329 /*Find a Free index*/
4330 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4331 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
4332 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4333 break;
4334 }
4335 }
4336
4337 if (i < drv_ctx.ip_buf.actualcount) {
4338 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4339
4340 if (buf_addr == NULL) {
4341 return OMX_ErrorInsufficientResources;
4342 }
4343
4344 *bufferHdr = (m_inp_heap_ptr + i);
4345 input = *bufferHdr;
4346 BITMASK_SET(&m_heap_inp_bm_count,i);
4347
4348 input->pBuffer = (OMX_U8 *)buf_addr;
4349 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4350 input->nVersion.nVersion = OMX_SPEC_VERSION;
4351 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4352 input->pAppPrivate = appData;
4353 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4354 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4355 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4356 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
4357 /*Add the Buffers to freeq*/
4358 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4359 (unsigned)NULL, (unsigned)NULL)) {
4360 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4361 return OMX_ErrorInsufficientResources;
4362 }
4363 } else {
4364 return OMX_ErrorBadParameter;
4365 }
4366
4367 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004368
4369}
4370
4371
4372/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004373 FUNCTION
4374 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004375
Arun Menon906de572013-06-18 17:01:40 -07004376 DESCRIPTION
4377 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004378
Arun Menon906de572013-06-18 17:01:40 -07004379 PARAMETERS
4380 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004381
Arun Menon906de572013-06-18 17:01:40 -07004382 RETURN VALUE
4383 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004384
Arun Menon906de572013-06-18 17:01:40 -07004385 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004386OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004387 OMX_IN OMX_HANDLETYPE hComp,
4388 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4389 OMX_IN OMX_U32 port,
4390 OMX_IN OMX_PTR appData,
4391 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004392{
4393
Arun Menon906de572013-06-18 17:01:40 -07004394 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4395 struct vdec_setbuffer_cmd setbuffers;
4396 OMX_BUFFERHEADERTYPE *input = NULL;
4397 unsigned i = 0;
4398 unsigned char *buf_addr = NULL;
4399 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004400
Arun Menon906de572013-06-18 17:01:40 -07004401 if (bytes != drv_ctx.ip_buf.buffer_size) {
4402 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
4403 bytes, drv_ctx.ip_buf.buffer_size);
4404 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004405 }
4406
Arun Menon906de572013-06-18 17:01:40 -07004407 if (!m_inp_mem_ptr) {
4408 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4409 drv_ctx.ip_buf.actualcount,
4410 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004411
Arun Menon906de572013-06-18 17:01:40 -07004412 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4413 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4414
4415 if (m_inp_mem_ptr == NULL) {
4416 return OMX_ErrorInsufficientResources;
4417 }
4418
4419 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4420 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4421
4422 if (drv_ctx.ptr_inputbuffer == NULL) {
4423 return OMX_ErrorInsufficientResources;
4424 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004425#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004426 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4427 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004428
Arun Menon906de572013-06-18 17:01:40 -07004429 if (drv_ctx.ip_buf_ion_info == NULL) {
4430 return OMX_ErrorInsufficientResources;
4431 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004432#endif
4433
Arun Menon906de572013-06-18 17:01:40 -07004434 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4435 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004436#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004437 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004438#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004439 }
4440 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004441
Arun Menon906de572013-06-18 17:01:40 -07004442 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4443 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4444 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4445 break;
4446 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004447 }
Arun Menon906de572013-06-18 17:01:40 -07004448
4449 if (i < drv_ctx.ip_buf.actualcount) {
4450 struct v4l2_buffer buf;
4451 struct v4l2_plane plane;
4452 int rc;
4453 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4454#ifdef USE_ION
4455 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4456 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4457 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4458 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4459 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4460 return OMX_ErrorInsufficientResources;
4461 }
4462 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4463#else
4464 pmem_fd = open (MEM_DEVICE,O_RDWR);
4465
4466 if (pmem_fd < 0) {
4467 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4468 return OMX_ErrorInsufficientResources;
4469 }
4470
4471 if (pmem_fd == 0) {
4472 pmem_fd = open (MEM_DEVICE,O_RDWR);
4473
4474 if (pmem_fd < 0) {
4475 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4476 return OMX_ErrorInsufficientResources;
4477 }
4478 }
4479
4480 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4481 drv_ctx.ip_buf.alignment)) {
4482 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4483 close(pmem_fd);
4484 return OMX_ErrorInsufficientResources;
4485 }
4486#endif
4487 if (!secure_mode) {
4488 buf_addr = (unsigned char *)mmap(NULL,
4489 drv_ctx.ip_buf.buffer_size,
4490 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4491
4492 if (buf_addr == MAP_FAILED) {
4493 close(pmem_fd);
4494#ifdef USE_ION
4495 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4496#endif
4497 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4498 return OMX_ErrorInsufficientResources;
4499 }
4500 }
4501 *bufferHdr = (m_inp_mem_ptr + i);
4502 if (secure_mode)
4503 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4504 else
4505 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4506 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4507 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4508 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4509 drv_ctx.ptr_inputbuffer [i].offset = 0;
4510
4511
4512 buf.index = i;
4513 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4514 buf.memory = V4L2_MEMORY_USERPTR;
4515 plane.bytesused = 0;
4516 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4517 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4518 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4519 plane.reserved[1] = 0;
4520 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4521 buf.m.planes = &plane;
4522 buf.length = 1;
4523
4524 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4525 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4526
4527 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4528
4529 if (rc) {
4530 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4531 /*TODO: How to handle this case */
4532 return OMX_ErrorInsufficientResources;
4533 }
4534
4535 input = *bufferHdr;
4536 BITMASK_SET(&m_inp_bm_count,i);
4537 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4538 if (secure_mode)
4539 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4540 else
4541 input->pBuffer = (OMX_U8 *)buf_addr;
4542 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4543 input->nVersion.nVersion = OMX_SPEC_VERSION;
4544 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4545 input->pAppPrivate = appData;
4546 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4547 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4548
4549 if (drv_ctx.disable_dmx) {
4550 eRet = allocate_desc_buffer(i);
4551 }
4552 } else {
4553 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4554 eRet = OMX_ErrorInsufficientResources;
4555 }
4556 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004557}
4558
4559
4560/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004561 FUNCTION
4562 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004563
Arun Menon906de572013-06-18 17:01:40 -07004564 DESCRIPTION
4565 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004566
Arun Menon906de572013-06-18 17:01:40 -07004567 PARAMETERS
4568 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004569
Arun Menon906de572013-06-18 17:01:40 -07004570 RETURN VALUE
4571 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004572
Arun Menon906de572013-06-18 17:01:40 -07004573 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004574OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004575 OMX_IN OMX_HANDLETYPE hComp,
4576 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4577 OMX_IN OMX_U32 port,
4578 OMX_IN OMX_PTR appData,
4579 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004580{
Arun Menon906de572013-06-18 17:01:40 -07004581 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4582 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4583 unsigned i= 0; // Temporary counter
4584 struct vdec_setbuffer_cmd setbuffers;
4585 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004586#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004587 int ion_device_fd =-1;
4588 struct ion_allocation_data ion_alloc_data;
4589 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004590#endif
Arun Menon906de572013-06-18 17:01:40 -07004591 if (!m_out_mem_ptr) {
4592 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4593 drv_ctx.op_buf.actualcount,
4594 drv_ctx.op_buf.buffer_size);
4595 int nBufHdrSize = 0;
4596 int nPlatformEntrySize = 0;
4597 int nPlatformListSize = 0;
4598 int nPMEMInfoSize = 0;
4599 int pmem_fd = -1;
4600 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004601
Arun Menon906de572013-06-18 17:01:40 -07004602 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4603 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4604 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004605
Arun Menon906de572013-06-18 17:01:40 -07004606 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4607 drv_ctx.op_buf.actualcount);
4608 nBufHdrSize = drv_ctx.op_buf.actualcount *
4609 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004610
Arun Menon906de572013-06-18 17:01:40 -07004611 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4612 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4613 nPlatformListSize = drv_ctx.op_buf.actualcount *
4614 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4615 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4616 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004617
Arun Menon906de572013-06-18 17:01:40 -07004618 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4619 sizeof(OMX_BUFFERHEADERTYPE),
4620 nPMEMInfoSize,
4621 nPlatformListSize);
4622 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4623 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004624#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004625 ion_device_fd = alloc_map_ion_memory(
4626 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4627 drv_ctx.op_buf.alignment,
4628 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4629 if (ion_device_fd < 0) {
4630 return OMX_ErrorInsufficientResources;
4631 }
4632 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004633#else
Arun Menon906de572013-06-18 17:01:40 -07004634 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004635
Arun Menon906de572013-06-18 17:01:40 -07004636 if (pmem_fd < 0) {
4637 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4638 drv_ctx.op_buf.buffer_size);
4639 return OMX_ErrorInsufficientResources;
4640 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004641
Arun Menon906de572013-06-18 17:01:40 -07004642 if (pmem_fd == 0) {
4643 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004644
Arun Menon906de572013-06-18 17:01:40 -07004645 if (pmem_fd < 0) {
4646 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4647 drv_ctx.op_buf.buffer_size);
4648 return OMX_ErrorInsufficientResources;
4649 }
4650 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004651
Arun Menon906de572013-06-18 17:01:40 -07004652 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4653 drv_ctx.op_buf.actualcount,
4654 drv_ctx.op_buf.alignment)) {
4655 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4656 close(pmem_fd);
4657 return OMX_ErrorInsufficientResources;
4658 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004659#endif
Arun Menon906de572013-06-18 17:01:40 -07004660 if (!secure_mode) {
4661 pmem_baseaddress = (unsigned char *)mmap(NULL,
4662 (drv_ctx.op_buf.buffer_size *
4663 drv_ctx.op_buf.actualcount),
4664 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4665 if (pmem_baseaddress == MAP_FAILED) {
4666 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4667 drv_ctx.op_buf.buffer_size);
4668 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004669#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004670 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004671#endif
Arun Menon906de572013-06-18 17:01:40 -07004672 return OMX_ErrorInsufficientResources;
4673 }
4674 }
4675 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4676 // Alloc mem for platform specific info
4677 char *pPtr=NULL;
4678 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4679 nPMEMInfoSize,1);
4680 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4681 calloc (sizeof(struct vdec_bufferpayload),
4682 drv_ctx.op_buf.actualcount);
4683 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4684 calloc (sizeof (struct vdec_output_frameinfo),
4685 drv_ctx.op_buf.actualcount);
4686#ifdef USE_ION
4687 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4688 calloc (sizeof(struct vdec_ion),
4689 drv_ctx.op_buf.actualcount);
4690#endif
4691
4692 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4693 && drv_ctx.ptr_respbuffer) {
4694 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4695 (drv_ctx.op_buf.buffer_size *
4696 drv_ctx.op_buf.actualcount);
4697 bufHdr = m_out_mem_ptr;
4698 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4699 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4700 (((char *) m_platform_list) + nPlatformListSize);
4701 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4702 (((char *) m_platform_entry) + nPlatformEntrySize);
4703 pPlatformList = m_platform_list;
4704 pPlatformEntry = m_platform_entry;
4705 pPMEMInfo = m_pmem_info;
4706
4707 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
4708
4709 // Settting the entire storage nicely
4710 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
4711 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
4712 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4713 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4714 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4715 // Set the values when we determine the right HxW param
4716 bufHdr->nAllocLen = bytes;
4717 bufHdr->nFilledLen = 0;
4718 bufHdr->pAppPrivate = appData;
4719 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4720 // Platform specific PMEM Information
4721 // Initialize the Platform Entry
4722 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
4723 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4724 pPlatformEntry->entry = pPMEMInfo;
4725 // Initialize the Platform List
4726 pPlatformList->nEntries = 1;
4727 pPlatformList->entryList = pPlatformEntry;
4728 // Keep pBuffer NULL till vdec is opened
4729 bufHdr->pBuffer = NULL;
4730 bufHdr->nOffset = 0;
4731
4732 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4733 pPMEMInfo->pmem_fd = 0;
4734 bufHdr->pPlatformPrivate = pPlatformList;
4735
4736 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
4737 m_pmem_info[i].pmem_fd = pmem_fd;
4738#ifdef USE_ION
4739 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
4740 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
4741 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
4742#endif
4743
4744 /*Create a mapping between buffers*/
4745 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
4746 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
4747 &drv_ctx.ptr_outputbuffer[i];
4748 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
4749 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4750 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
4751
4752 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
4753 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
4754 drv_ctx.ptr_outputbuffer[i].bufferaddr);
4755 // Move the buffer and buffer header pointers
4756 bufHdr++;
4757 pPMEMInfo++;
4758 pPlatformEntry++;
4759 pPlatformList++;
4760 }
4761 } else {
4762 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
4763 m_out_mem_ptr, pPtr);
4764 if (m_out_mem_ptr) {
4765 free(m_out_mem_ptr);
4766 m_out_mem_ptr = NULL;
4767 }
4768 if (pPtr) {
4769 free(pPtr);
4770 pPtr = NULL;
4771 }
4772 if (drv_ctx.ptr_outputbuffer) {
4773 free(drv_ctx.ptr_outputbuffer);
4774 drv_ctx.ptr_outputbuffer = NULL;
4775 }
4776 if (drv_ctx.ptr_respbuffer) {
4777 free(drv_ctx.ptr_respbuffer);
4778 drv_ctx.ptr_respbuffer = NULL;
4779 }
4780#ifdef USE_ION
4781 if (drv_ctx.op_buf_ion_info) {
4782 DEBUG_PRINT_LOW("\n Free o/p ion context");
4783 free(drv_ctx.op_buf_ion_info);
4784 drv_ctx.op_buf_ion_info = NULL;
4785 }
4786#endif
4787 eRet = OMX_ErrorInsufficientResources;
4788 }
4789 if (eRet == OMX_ErrorNone)
4790 eRet = allocate_extradata();
4791 }
4792
4793 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4794 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4795 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
4796 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004797 }
4798 }
Arun Menon906de572013-06-18 17:01:40 -07004799
4800 if (eRet == OMX_ErrorNone) {
4801 if (i < drv_ctx.op_buf.actualcount) {
4802 struct v4l2_buffer buf;
4803 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4804 int rc;
4805 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4806
4807 drv_ctx.ptr_outputbuffer[i].buffer_len =
4808 drv_ctx.op_buf.buffer_size;
4809
4810 *bufferHdr = (m_out_mem_ptr + i );
4811 if (secure_mode) {
4812 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4813 }
4814 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
4815
4816 buf.index = i;
4817 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4818 buf.memory = V4L2_MEMORY_USERPTR;
4819 plane[0].length = drv_ctx.op_buf.buffer_size;
4820 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4821 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004822#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004823 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004824#endif
Arun Menon906de572013-06-18 17:01:40 -07004825 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4826 plane[0].data_offset = 0;
4827 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4828 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4829 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4830 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 -07004831#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004832 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004833#endif
Arun Menon906de572013-06-18 17:01:40 -07004834 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4835 plane[extra_idx].data_offset = 0;
4836 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4837 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
4838 return OMX_ErrorBadParameter;
4839 }
4840 buf.m.planes = plane;
4841 buf.length = drv_ctx.num_planes;
4842 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
4843 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4844 if (rc) {
4845 /*TODO: How to handle this case */
4846 return OMX_ErrorInsufficientResources;
4847 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004848
Arun Menon906de572013-06-18 17:01:40 -07004849 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
4850 enum v4l2_buf_type buf_type;
4851 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4852 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
4853 if (rc) {
4854 return OMX_ErrorInsufficientResources;
4855 } else {
4856 streaming[CAPTURE_PORT] = true;
4857 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4858 }
4859 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004860
Arun Menon906de572013-06-18 17:01:40 -07004861 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
4862 (*bufferHdr)->pAppPrivate = appData;
4863 BITMASK_SET(&m_out_bm_count,i);
4864 } else {
4865 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
4866 eRet = OMX_ErrorInsufficientResources;
4867 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004868 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004869
Arun Menon906de572013-06-18 17:01:40 -07004870 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004871}
4872
4873
4874// AllocateBuffer -- API Call
4875/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004876 FUNCTION
4877 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004878
Arun Menon906de572013-06-18 17:01:40 -07004879 DESCRIPTION
4880 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07004881
Arun Menon906de572013-06-18 17:01:40 -07004882 PARAMETERS
4883 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004884
Arun Menon906de572013-06-18 17:01:40 -07004885 RETURN VALUE
4886 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004887
Arun Menon906de572013-06-18 17:01:40 -07004888 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004889OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004890 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4891 OMX_IN OMX_U32 port,
4892 OMX_IN OMX_PTR appData,
4893 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004894{
4895 unsigned i = 0;
4896 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
4897
4898 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07004899 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004900 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
4901 return OMX_ErrorInvalidState;
4902 }
4903
Arun Menon906de572013-06-18 17:01:40 -07004904 if (port == OMX_CORE_INPUT_PORT_INDEX) {
4905 if (arbitrary_bytes) {
4906 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
4907 } else {
4908 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
4909 }
4910 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08004911 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
4912 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07004913 } else {
4914 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4915 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004916 }
4917 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07004918 if (eRet == OMX_ErrorNone) {
4919 if (allocate_done()) {
4920 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004921 // Send the callback now
4922 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4923 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07004924 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004925 }
4926 }
Arun Menon906de572013-06-18 17:01:40 -07004927 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
4928 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4929 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4930 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004931 OMX_CORE_INPUT_PORT_INDEX,
4932 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07004933 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004934 }
Arun Menon906de572013-06-18 17:01:40 -07004935 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
4936 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4937 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004938 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07004939 OMX_CORE_OUTPUT_PORT_INDEX,
4940 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004941 }
4942 }
4943 }
4944 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
4945 return eRet;
4946}
4947
4948// Free Buffer - API call
4949/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004950 FUNCTION
4951 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004952
Arun Menon906de572013-06-18 17:01:40 -07004953 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07004954
Arun Menon906de572013-06-18 17:01:40 -07004955 PARAMETERS
4956 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004957
Arun Menon906de572013-06-18 17:01:40 -07004958 RETURN VALUE
4959 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004960
Arun Menon906de572013-06-18 17:01:40 -07004961 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004962OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004963 OMX_IN OMX_U32 port,
4964 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004965{
4966 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4967 unsigned int nPortIndex;
4968 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
4969
Arun Menon906de572013-06-18 17:01:40 -07004970 if (m_state == OMX_StateIdle &&
4971 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004972 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
Arun Menon906de572013-06-18 17:01:40 -07004973 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
4974 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07004975 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Arun Menon906de572013-06-18 17:01:40 -07004976 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
4977 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
4978 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
4979 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Arun Menon9f098152013-05-08 13:53:54 -07004980 DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port);
Arun Menon906de572013-06-18 17:01:40 -07004981 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004982 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
4983 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07004984 OMX_ErrorPortUnpopulated,
4985 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004986
4987 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07004988 } else if (m_state != OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004989 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
4990 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07004991 OMX_ErrorPortUnpopulated,
4992 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004993 }
4994
Arun Menon906de572013-06-18 17:01:40 -07004995 if (port == OMX_CORE_INPUT_PORT_INDEX) {
4996 /*Check if arbitrary bytes*/
4997 if (!arbitrary_bytes && !input_use_buffer)
4998 nPortIndex = buffer - m_inp_mem_ptr;
4999 else
5000 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005001
5002 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005003 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5004 // Clear the bit associated with it.
5005 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5006 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5007 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005008
Arun Menon906de572013-06-18 17:01:40 -07005009 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5010 if (m_phdr_pmem_ptr)
5011 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5012 } else {
5013 if (arbitrary_bytes) {
5014 if (m_phdr_pmem_ptr)
5015 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5016 else
5017 free_input_buffer(nPortIndex,NULL);
5018 } else
5019 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005020 }
Arun Menon906de572013-06-18 17:01:40 -07005021 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305022 if(release_input_done())
5023 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005024 /*Free the Buffer Header*/
5025 if (release_input_done()) {
5026 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5027 free_input_buffer_header();
5028 }
5029 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005030 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5031 eRet = OMX_ErrorBadPortIndex;
5032 }
5033
Arun Menon906de572013-06-18 17:01:40 -07005034 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5035 && release_input_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005036 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5037 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5038 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005039 OMX_CORE_INPUT_PORT_INDEX,
5040 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005041 }
Arun Menon906de572013-06-18 17:01:40 -07005042 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005043 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005044 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005045 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005046 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5047 // Clear the bit associated with it.
5048 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5049 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005050 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005051
Surajit Podder12aefac2013-08-06 18:43:32 +05305052 if(release_output_done()) {
5053 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5054 }
Arun Menon906de572013-06-18 17:01:40 -07005055 if (release_output_done()) {
5056 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005057 }
Arun Menon906de572013-06-18 17:01:40 -07005058 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005059 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5060 eRet = OMX_ErrorBadPortIndex;
5061 }
Arun Menon906de572013-06-18 17:01:40 -07005062 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5063 && release_output_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005064 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5065
Arun Menon906de572013-06-18 17:01:40 -07005066 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5067 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005068#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005069 if (m_enable_android_native_buffers) {
5070 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5071 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5072 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005073#endif
5074
Arun Menon906de572013-06-18 17:01:40 -07005075 post_event(OMX_CommandPortDisable,
5076 OMX_CORE_OUTPUT_PORT_INDEX,
5077 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005078 }
Arun Menon906de572013-06-18 17:01:40 -07005079 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005080 eRet = OMX_ErrorBadPortIndex;
5081 }
Arun Menon906de572013-06-18 17:01:40 -07005082 if ((eRet == OMX_ErrorNone) &&
5083 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5084 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005085 // Send the callback now
5086 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5087 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005088 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005089 }
5090 }
5091 return eRet;
5092}
5093
5094
5095/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005096 FUNCTION
5097 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005098
Arun Menon906de572013-06-18 17:01:40 -07005099 DESCRIPTION
5100 This routine is used to push the encoded video frames to
5101 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005102
Arun Menon906de572013-06-18 17:01:40 -07005103 PARAMETERS
5104 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005105
Arun Menon906de572013-06-18 17:01:40 -07005106 RETURN VALUE
5107 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005108
Arun Menon906de572013-06-18 17:01:40 -07005109 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005110OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005111 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005112{
Arun Menon906de572013-06-18 17:01:40 -07005113 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5114 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005115
Arun Menon906de572013-06-18 17:01:40 -07005116 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5117 codec_config_flag = true;
5118 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5119 } else {
5120 codec_config_flag = false;
5121 }
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07005122
Arun Menon906de572013-06-18 17:01:40 -07005123 if (m_state == OMX_StateInvalid) {
5124 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5125 return OMX_ErrorInvalidState;
5126 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005127
Arun Menon906de572013-06-18 17:01:40 -07005128 if (buffer == NULL) {
5129 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5130 return OMX_ErrorBadParameter;
5131 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005132
Arun Menon906de572013-06-18 17:01:40 -07005133 if (!m_inp_bEnabled) {
5134 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5135 return OMX_ErrorIncorrectStateOperation;
5136 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005137
Arun Menon906de572013-06-18 17:01:40 -07005138 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
5139 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
5140 return OMX_ErrorBadPortIndex;
5141 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005142
5143#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005144 if (iDivXDrmDecrypt) {
5145 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5146 if (drmErr != OMX_ErrorNone) {
5147 // this error can be ignored
5148 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5149 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005150 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005151#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005152 if (perf_flag) {
5153 if (!latency) {
5154 dec_time.stop();
5155 latency = dec_time.processing_time_us();
5156 dec_time.start();
5157 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005158 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005159
Arun Menon906de572013-06-18 17:01:40 -07005160 if (arbitrary_bytes) {
5161 nBufferIndex = buffer - m_inp_heap_ptr;
5162 } else {
5163 if (input_use_buffer == true) {
5164 nBufferIndex = buffer - m_inp_heap_ptr;
5165 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5166 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5167 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5168 buffer = &m_inp_mem_ptr[nBufferIndex];
5169 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5170 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5171 } else {
5172 nBufferIndex = buffer - m_inp_mem_ptr;
5173 }
5174 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005175
Arun Menon906de572013-06-18 17:01:40 -07005176 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
5177 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5178 return OMX_ErrorBadParameter;
5179 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005180
Arun Menon906de572013-06-18 17:01:40 -07005181 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5182 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5183 if (arbitrary_bytes) {
5184 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005185 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005186 } else {
5187 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5188 set_frame_rate(buffer->nTimeStamp);
5189 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5190 }
5191 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005192}
5193
5194/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005195 FUNCTION
5196 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005197
Arun Menon906de572013-06-18 17:01:40 -07005198 DESCRIPTION
5199 This routine is used to push the encoded video frames to
5200 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005201
Arun Menon906de572013-06-18 17:01:40 -07005202 PARAMETERS
5203 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005204
Arun Menon906de572013-06-18 17:01:40 -07005205 RETURN VALUE
5206 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005207
Arun Menon906de572013-06-18 17:01:40 -07005208 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005209OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005210 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005211{
Arun Menon906de572013-06-18 17:01:40 -07005212 int push_cnt = 0,i=0;
5213 unsigned nPortIndex = 0;
5214 OMX_ERRORTYPE ret = OMX_ErrorNone;
5215 struct vdec_input_frameinfo frameinfo;
5216 struct vdec_bufferpayload *temp_buffer;
5217 struct vdec_seqheader seq_header;
5218 bool port_setting_changed = true;
5219 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005220
Arun Menon906de572013-06-18 17:01:40 -07005221 /*Should we generate a Aync error event*/
5222 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
5223 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5224 return OMX_ErrorBadParameter;
5225 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005226
Arun Menon906de572013-06-18 17:01:40 -07005227 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005228
Arun Menon906de572013-06-18 17:01:40 -07005229 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
5230 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5231 nPortIndex);
5232 return OMX_ErrorBadParameter;
5233 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005234
Arun Menon906de572013-06-18 17:01:40 -07005235 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005236
Arun Menon906de572013-06-18 17:01:40 -07005237 /* return zero length and not an EOS buffer */
5238 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5239 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
5240 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5241 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5242 OMX_COMPONENT_GENERATE_EBD);
5243 return OMX_ErrorNone;
5244 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005245
5246
Arun Menon906de572013-06-18 17:01:40 -07005247 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5248 mp4StreamType psBits;
5249 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5250 psBits.numBytes = buffer->nFilledLen;
5251 mp4_headerparser.parseHeader(&psBits);
5252 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5253 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5254 if (not_coded_vop) {
5255 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
5256 buffer->nFilledLen,frame_count);
5257 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
5258 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5259 not_coded_vop = false;
5260 buffer->nFilledLen = 0;
5261 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005262 }
5263 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005264
Arun Menon906de572013-06-18 17:01:40 -07005265 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005266
Arun Menon906de572013-06-18 17:01:40 -07005267 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005268
Arun Menon906de572013-06-18 17:01:40 -07005269 ) {
5270 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5271 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5272 OMX_COMPONENT_GENERATE_EBD);
5273 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005274 }
5275
Arun Menon906de572013-06-18 17:01:40 -07005276 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005277
Arun Menon906de572013-06-18 17:01:40 -07005278 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) {
5279 return OMX_ErrorBadParameter;
5280 }
5281 /* If its first frame, H264 codec and reject is true, then parse the nal
5282 and get the profile. Based on this, reject the clip playback */
5283 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5284 m_reject_avc_1080p_mp) {
5285 first_frame = 1;
5286 DEBUG_PRINT_ERROR("\nParse nal to get the profile");
5287 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5288 NALU_TYPE_SPS);
5289 m_profile = h264_parser->get_profile();
5290 ret = is_video_session_supported();
5291 if (ret) {
5292 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5293 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5294 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5295 m_state = OMX_StateInvalid;
5296 return OMX_ErrorNone;
5297 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005298 }
5299
Arun Menon906de572013-06-18 17:01:40 -07005300 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5301 /*for use buffer we need to memcpy the data*/
5302 temp_buffer->buffer_len = buffer->nFilledLen;
5303
5304 if (input_use_buffer) {
5305 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5306 if (arbitrary_bytes) {
5307 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5308 } else {
5309 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5310 buffer->nFilledLen);
5311 }
5312 } else {
5313 return OMX_ErrorBadParameter;
5314 }
5315
5316 }
5317
5318 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5319 frameinfo.client_data = (void *) buffer;
5320 frameinfo.datalen = temp_buffer->buffer_len;
5321 frameinfo.flags = 0;
5322 frameinfo.offset = buffer->nOffset;
5323 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5324 frameinfo.pmem_offset = temp_buffer->offset;
5325 frameinfo.timestamp = buffer->nTimeStamp;
5326 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5327 DEBUG_PRINT_LOW("ETB: dmx enabled");
5328 if (m_demux_entries == 0) {
5329 extract_demux_addr_offsets(buffer);
5330 }
5331
5332 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5333 handle_demux_data(buffer);
5334 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5335 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5336 } else {
5337 frameinfo.desc_addr = NULL;
5338 frameinfo.desc_size = 0;
5339 }
5340 if (!arbitrary_bytes) {
5341 frameinfo.flags |= buffer->nFlags;
5342 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005343
5344#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005345 if (m_debug_timestamp) {
5346 if (arbitrary_bytes) {
5347 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5348 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5349 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5350 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5351 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5352 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005353 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005354#endif
5355
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005356log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005357
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005358if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005359 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5360 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5361 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005362
Arun Menon906de572013-06-18 17:01:40 -07005363 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5364 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5365 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5366 h264_scratch.nFilledLen = 0;
5367 nal_count = 0;
5368 look_ahead_nal = false;
5369 frame_count = 0;
5370 if (m_frame_parser.mutils)
5371 m_frame_parser.mutils->initialize_frame_checking_environment();
5372 m_frame_parser.flush();
5373 h264_last_au_ts = LLONG_MAX;
5374 h264_last_au_flags = 0;
5375 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5376 m_demux_entries = 0;
5377 }
5378 struct v4l2_buffer buf;
5379 struct v4l2_plane plane;
5380 memset( (void *)&buf, 0, sizeof(buf));
5381 memset( (void *)&plane, 0, sizeof(plane));
5382 int rc;
5383 unsigned long print_count;
5384 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5385 buf.flags = V4L2_BUF_FLAG_EOS;
5386 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
5387 }
5388 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5389 buf.index = nPortIndex;
5390 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5391 buf.memory = V4L2_MEMORY_USERPTR;
5392 plane.bytesused = temp_buffer->buffer_len;
5393 plane.length = drv_ctx.ip_buf.buffer_size;
5394 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5395 (unsigned long)temp_buffer->offset;
5396 plane.reserved[0] = temp_buffer->pmem_fd;
5397 plane.reserved[1] = temp_buffer->offset;
5398 plane.data_offset = 0;
5399 buf.m.planes = &plane;
5400 buf.length = 1;
5401 if (frameinfo.timestamp >= LLONG_MAX) {
5402 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5403 }
5404 //assumption is that timestamp is in milliseconds
5405 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5406 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5407 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5408 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005409
Arun Menon906de572013-06-18 17:01:40 -07005410 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5411 if (rc) {
5412 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5413 return OMX_ErrorHardware;
5414 }
5415 if (!streaming[OUTPUT_PORT]) {
5416 enum v4l2_buf_type buf_type;
5417 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005418
Arun Menon906de572013-06-18 17:01:40 -07005419 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005420 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
Arun Menon906de572013-06-18 17:01:40 -07005421 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5422 if (!ret) {
5423 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
5424 streaming[OUTPUT_PORT] = true;
5425 } else {
5426 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
5427 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5428 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5429 OMX_COMPONENT_GENERATE_EBD);
5430 return OMX_ErrorBadParameter;
5431 }
5432 }
5433 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5434 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5435 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005436
Arun Menon906de572013-06-18 17:01:40 -07005437 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005438}
5439
5440/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005441 FUNCTION
5442 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005443
Arun Menon906de572013-06-18 17:01:40 -07005444 DESCRIPTION
5445 IL client uses this method to release the frame buffer
5446 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005447
Arun Menon906de572013-06-18 17:01:40 -07005448 PARAMETERS
5449 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005450
Arun Menon906de572013-06-18 17:01:40 -07005451 RETURN VALUE
5452 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005453
Arun Menon906de572013-06-18 17:01:40 -07005454 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005455OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005456 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005457{
5458
Arun Menon906de572013-06-18 17:01:40 -07005459 if (m_state == OMX_StateInvalid) {
5460 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5461 return OMX_ErrorInvalidState;
5462 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005463
Arun Menon906de572013-06-18 17:01:40 -07005464 if (!m_out_bEnabled) {
5465 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5466 return OMX_ErrorIncorrectStateOperation;
5467 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005468
Arun Menon906de572013-06-18 17:01:40 -07005469 if (buffer == NULL ||
5470 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) {
5471 return OMX_ErrorBadParameter;
5472 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005473
Arun Menon906de572013-06-18 17:01:40 -07005474 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
5475 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
5476 return OMX_ErrorBadPortIndex;
5477 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005478
Arun Menon906de572013-06-18 17:01:40 -07005479 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5480 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5481 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005482}
5483/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005484 FUNCTION
5485 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005486
Arun Menon906de572013-06-18 17:01:40 -07005487 DESCRIPTION
5488 IL client uses this method to release the frame buffer
5489 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005490
Arun Menon906de572013-06-18 17:01:40 -07005491 PARAMETERS
5492 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005493
Arun Menon906de572013-06-18 17:01:40 -07005494 RETURN VALUE
5495 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005496
Arun Menon906de572013-06-18 17:01:40 -07005497 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005498OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005499 OMX_IN OMX_HANDLETYPE hComp,
5500 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005501{
Arun Menon906de572013-06-18 17:01:40 -07005502 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5503 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5504 unsigned nPortIndex = 0;
5505 struct vdec_fillbuffer_cmd fillbuffer;
5506 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5507 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005508
Arun Menon906de572013-06-18 17:01:40 -07005509 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005510
Arun Menon906de572013-06-18 17:01:40 -07005511 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5512 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005513
Arun Menon906de572013-06-18 17:01:40 -07005514 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5515 bufferAdd, bufferAdd->pBuffer);
5516 /*Return back the output buffer to client*/
5517 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
5518 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5519 buffer->nFilledLen = 0;
5520 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5521 return OMX_ErrorNone;
5522 }
5523 pending_output_buffers++;
5524 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5525 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5526 if (ptr_respbuffer) {
5527 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5528 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005529
Arun Menon906de572013-06-18 17:01:40 -07005530 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5531 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5532 buffer->nFilledLen = 0;
5533 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5534 pending_output_buffers--;
5535 return OMX_ErrorBadParameter;
5536 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005537
Arun Menon906de572013-06-18 17:01:40 -07005538 int rc = 0;
5539 struct v4l2_buffer buf;
5540 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5541 memset( (void *)&buf, 0, sizeof(buf));
5542 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5543 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005544
Arun Menon906de572013-06-18 17:01:40 -07005545 buf.index = nPortIndex;
5546 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5547 buf.memory = V4L2_MEMORY_USERPTR;
5548 plane[0].bytesused = buffer->nFilledLen;
5549 plane[0].length = drv_ctx.op_buf.buffer_size;
5550 plane[0].m.userptr =
5551 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5552 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5553 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5554 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5555 plane[0].data_offset = 0;
5556 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5557 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5558 plane[extra_idx].bytesused = 0;
5559 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5560 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 -07005561#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005562 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005563#endif
Arun Menon906de572013-06-18 17:01:40 -07005564 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5565 plane[extra_idx].data_offset = 0;
5566 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5567 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5568 return OMX_ErrorBadParameter;
5569 }
5570 buf.m.planes = plane;
5571 buf.length = drv_ctx.num_planes;
5572 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5573 if (rc) {
5574 /*TODO: How to handle this case */
5575 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5576 }
Arun Menon906de572013-06-18 17:01:40 -07005577return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005578}
5579
5580/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005581 FUNCTION
5582 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005583
Arun Menon906de572013-06-18 17:01:40 -07005584 DESCRIPTION
5585 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005586
Arun Menon906de572013-06-18 17:01:40 -07005587 PARAMETERS
5588 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005589
Arun Menon906de572013-06-18 17:01:40 -07005590 RETURN VALUE
5591 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005592
Arun Menon906de572013-06-18 17:01:40 -07005593 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005594OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005595 OMX_IN OMX_CALLBACKTYPE* callbacks,
5596 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005597{
5598
Arun Menon906de572013-06-18 17:01:40 -07005599 m_cb = *callbacks;
5600 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5601 m_cb.EventHandler,m_cb.FillBufferDone);
5602 m_app_data = appData;
5603 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005604}
5605
5606/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005607 FUNCTION
5608 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005609
Arun Menon906de572013-06-18 17:01:40 -07005610 DESCRIPTION
5611 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005612
Arun Menon906de572013-06-18 17:01:40 -07005613 PARAMETERS
5614 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005615
Arun Menon906de572013-06-18 17:01:40 -07005616 RETURN VALUE
5617 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005618
Arun Menon906de572013-06-18 17:01:40 -07005619 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005620OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5621{
5622#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005623 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005624 delete iDivXDrmDecrypt;
5625 iDivXDrmDecrypt=NULL;
5626 }
5627#endif //_ANDROID_
5628
Shalaj Jain286b0062013-02-21 20:35:48 -08005629 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005630 if (OMX_StateLoaded != m_state) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005631 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
Arun Menon906de572013-06-18 17:01:40 -07005632 m_state);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005633 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005634 } else {
5635 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005636 }
5637
5638 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005639 if (m_out_mem_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005640 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005641 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5642 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005643 }
5644#ifdef _ANDROID_ICS_
5645 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5646#endif
5647 }
5648
5649 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005650 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005651 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005652 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5653 if (m_inp_mem_ptr)
5654 free_input_buffer (i,&m_inp_mem_ptr[i]);
5655 else
5656 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005657 }
5658 }
5659 free_input_buffer_header();
5660 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005661 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005662 free(h264_scratch.pBuffer);
5663 h264_scratch.pBuffer = NULL;
5664 }
5665
Arun Menon906de572013-06-18 17:01:40 -07005666 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005667 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005668 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005669 }
5670
Arun Menon906de572013-06-18 17:01:40 -07005671 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005672 free(m_platform_list);
5673 m_platform_list = NULL;
5674 }
Arun Menon906de572013-06-18 17:01:40 -07005675 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005676 free(m_vendor_config.pData);
5677 m_vendor_config.pData = NULL;
5678 }
5679
5680 // Reset counters in mesg queues
5681 m_ftb_q.m_size=0;
5682 m_cmd_q.m_size=0;
5683 m_etb_q.m_size=0;
5684 m_ftb_q.m_read = m_ftb_q.m_write =0;
5685 m_cmd_q.m_read = m_cmd_q.m_write =0;
5686 m_etb_q.m_read = m_etb_q.m_write =0;
5687#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005688 if (m_debug_timestamp) {
5689 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005690 }
5691#endif
5692
5693 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
5694 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07005695 // NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005696 DEBUG_PRINT_HIGH("\n Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07005697
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005698 if (m_debug.infile) {
5699 fclose(m_debug.infile);
5700 m_debug.infile = NULL;
5701 }
5702 if (m_debug.outfile) {
5703 fclose(m_debug.outfile);
5704 m_debug.outfile = NULL;
5705 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005706#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07005707 if (outputExtradataFile)
5708 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005709#endif
Arun Menon906de572013-06-18 17:01:40 -07005710 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
5711 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005712}
5713
5714/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005715 FUNCTION
5716 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07005717
Arun Menon906de572013-06-18 17:01:40 -07005718 DESCRIPTION
5719 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005720
Arun Menon906de572013-06-18 17:01:40 -07005721 PARAMETERS
5722 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005723
Arun Menon906de572013-06-18 17:01:40 -07005724 RETURN VALUE
5725 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005726
Arun Menon906de572013-06-18 17:01:40 -07005727 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005728OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005729 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5730 OMX_IN OMX_U32 port,
5731 OMX_IN OMX_PTR appData,
5732 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005733{
Arun Menon906de572013-06-18 17:01:40 -07005734 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
5735 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
5736 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005737
5738#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005739 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
5740 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005741#else
Arun Menon906de572013-06-18 17:01:40 -07005742 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005743#endif
Arun Menon906de572013-06-18 17:01:40 -07005744 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
5745 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
5746 DEBUG_PRINT_ERROR("\n ");
5747 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005748#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005749 if (m_display_id == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005750 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
5751 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005752 }
5753 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
5754 eglGetProcAddress("eglQueryImageKHR");
5755 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
5756 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
5757 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005758#else //with OMX test app
5759 struct temp_egl {
5760 int pmem_fd;
5761 int offset;
5762 };
5763 struct temp_egl *temp_egl_id = NULL;
5764 void * pmemPtr = (void *) eglImage;
5765 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07005766 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005767 fd = temp_egl_id->pmem_fd;
5768 offset = temp_egl_id->offset;
5769 }
5770#endif
5771 if (fd < 0) {
5772 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
5773 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005774 }
5775 pmem_info.pmem_fd = (OMX_U32) fd;
5776 pmem_info.offset = (OMX_U32) offset;
5777 pmem_entry.entry = (void *) &pmem_info;
5778 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5779 pmem_list.entryList = &pmem_entry;
5780 pmem_list.nEntries = 1;
5781 ouput_egl_buffers = true;
5782 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
5783 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
5784 (OMX_U8 *)pmemPtr)) {
5785 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
5786 return OMX_ErrorInsufficientResources;
5787 }
5788 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005789}
5790
5791/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005792 FUNCTION
5793 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07005794
Arun Menon906de572013-06-18 17:01:40 -07005795 DESCRIPTION
5796 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005797
Arun Menon906de572013-06-18 17:01:40 -07005798 PARAMETERS
5799 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005800
Arun Menon906de572013-06-18 17:01:40 -07005801 RETURN VALUE
5802 OMX Error None if everything is successful.
5803 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005804OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005805 OMX_OUT OMX_U8* role,
5806 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005807{
Arun Menon906de572013-06-18 17:01:40 -07005808 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005809
Arun Menon906de572013-06-18 17:01:40 -07005810 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
5811 if ((0 == index) && role) {
5812 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
5813 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5814 } else {
5815 eRet = OMX_ErrorNoMore;
5816 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005817 }
Arun Menon906de572013-06-18 17:01:40 -07005818 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
5819 if ((0 == index) && role) {
5820 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
5821 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5822 } else {
5823 eRet = OMX_ErrorNoMore;
5824 }
5825 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
5826 if ((0 == index) && role) {
5827 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
5828 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5829 } else {
5830 DEBUG_PRINT_LOW("\n No more roles \n");
5831 eRet = OMX_ErrorNoMore;
5832 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005833 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005834
Arun Menon906de572013-06-18 17:01:40 -07005835 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
5836 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
5837 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07005838
Shalaj Jain273b3e02012-06-22 19:08:03 -07005839 {
Arun Menon906de572013-06-18 17:01:40 -07005840 if ((0 == index) && role) {
5841 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
5842 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5843 } else {
5844 DEBUG_PRINT_LOW("\n No more roles \n");
5845 eRet = OMX_ErrorNoMore;
5846 }
5847 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
5848 if ((0 == index) && role) {
5849 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
5850 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5851 } else {
5852 DEBUG_PRINT_LOW("\n No more roles \n");
5853 eRet = OMX_ErrorNoMore;
5854 }
5855 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
5856 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
5857 ) {
5858 if ((0 == index) && role) {
5859 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
5860 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5861 } else {
5862 DEBUG_PRINT_LOW("\n No more roles \n");
5863 eRet = OMX_ErrorNoMore;
5864 }
5865 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
5866 if ((0 == index) && role) {
5867 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
5868 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5869 } else {
5870 DEBUG_PRINT_LOW("\n No more roles \n");
5871 eRet = OMX_ErrorNoMore;
5872 }
5873 } else {
5874 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
5875 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005876 }
Arun Menon906de572013-06-18 17:01:40 -07005877 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005878}
5879
5880
5881
5882
5883/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005884 FUNCTION
5885 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07005886
Arun Menon906de572013-06-18 17:01:40 -07005887 DESCRIPTION
5888 Checks if entire buffer pool is allocated by IL Client or not.
5889 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005890
Arun Menon906de572013-06-18 17:01:40 -07005891 PARAMETERS
5892 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005893
Arun Menon906de572013-06-18 17:01:40 -07005894 RETURN VALUE
5895 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005896
Arun Menon906de572013-06-18 17:01:40 -07005897 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005898bool omx_vdec::allocate_done(void)
5899{
Arun Menon906de572013-06-18 17:01:40 -07005900 bool bRet = false;
5901 bool bRet_In = false;
5902 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005903
Arun Menon906de572013-06-18 17:01:40 -07005904 bRet_In = allocate_input_done();
5905 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005906
Arun Menon906de572013-06-18 17:01:40 -07005907 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005908 bRet = true;
5909 }
Arun Menon906de572013-06-18 17:01:40 -07005910
5911 return bRet;
5912}
5913/* ======================================================================
5914 FUNCTION
5915 omx_vdec::AllocateInputDone
5916
5917 DESCRIPTION
5918 Checks if I/P buffer pool is allocated by IL Client or not.
5919
5920 PARAMETERS
5921 None.
5922
5923 RETURN VALUE
5924 true/false.
5925
5926 ========================================================================== */
5927bool omx_vdec::allocate_input_done(void)
5928{
5929 bool bRet = false;
5930 unsigned i=0;
5931
5932 if (m_inp_mem_ptr == NULL) {
5933 return bRet;
5934 }
5935 if (m_inp_mem_ptr ) {
5936 for (; i<drv_ctx.ip_buf.actualcount; i++) {
5937 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
5938 break;
5939 }
5940 }
5941 }
5942 if (i == drv_ctx.ip_buf.actualcount) {
5943 bRet = true;
5944 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
5945 }
5946 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
5947 m_inp_bPopulated = OMX_TRUE;
5948 }
5949 return bRet;
5950}
5951/* ======================================================================
5952 FUNCTION
5953 omx_vdec::AllocateOutputDone
5954
5955 DESCRIPTION
5956 Checks if entire O/P buffer pool is allocated by IL Client or not.
5957
5958 PARAMETERS
5959 None.
5960
5961 RETURN VALUE
5962 true/false.
5963
5964 ========================================================================== */
5965bool omx_vdec::allocate_output_done(void)
5966{
5967 bool bRet = false;
5968 unsigned j=0;
5969
5970 if (m_out_mem_ptr == NULL) {
5971 return bRet;
5972 }
5973
5974 if (m_out_mem_ptr) {
5975 for (; j < drv_ctx.op_buf.actualcount; j++) {
5976 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
5977 break;
5978 }
5979 }
5980 }
5981
5982 if (j == drv_ctx.op_buf.actualcount) {
5983 bRet = true;
5984 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
5985 if (m_out_bEnabled)
5986 m_out_bPopulated = OMX_TRUE;
5987 }
5988
5989 return bRet;
5990}
5991
5992/* ======================================================================
5993 FUNCTION
5994 omx_vdec::ReleaseDone
5995
5996 DESCRIPTION
5997 Checks if IL client has released all the buffers.
5998
5999 PARAMETERS
6000 None.
6001
6002 RETURN VALUE
6003 true/false
6004
6005 ========================================================================== */
6006bool omx_vdec::release_done(void)
6007{
6008 bool bRet = false;
6009
6010 if (release_input_done()) {
6011 if (release_output_done()) {
6012 bRet = true;
6013 }
6014 }
6015 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006016}
6017
6018
6019/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006020 FUNCTION
6021 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006022
Arun Menon906de572013-06-18 17:01:40 -07006023 DESCRIPTION
6024 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006025
Arun Menon906de572013-06-18 17:01:40 -07006026 PARAMETERS
6027 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006028
Arun Menon906de572013-06-18 17:01:40 -07006029 RETURN VALUE
6030 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006031
Arun Menon906de572013-06-18 17:01:40 -07006032 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006033bool omx_vdec::release_output_done(void)
6034{
Arun Menon906de572013-06-18 17:01:40 -07006035 bool bRet = false;
6036 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006037
Arun Menon906de572013-06-18 17:01:40 -07006038 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6039 if (m_out_mem_ptr) {
6040 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6041 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6042 break;
6043 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006044 }
Arun Menon906de572013-06-18 17:01:40 -07006045 if (j == drv_ctx.op_buf.actualcount) {
6046 m_out_bm_count = 0;
6047 bRet = true;
6048 }
6049 } else {
6050 m_out_bm_count = 0;
6051 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006052 }
Arun Menon906de572013-06-18 17:01:40 -07006053 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006054}
6055/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006056 FUNCTION
6057 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006058
Arun Menon906de572013-06-18 17:01:40 -07006059 DESCRIPTION
6060 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006061
Arun Menon906de572013-06-18 17:01:40 -07006062 PARAMETERS
6063 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006064
Arun Menon906de572013-06-18 17:01:40 -07006065 RETURN VALUE
6066 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006067
Arun Menon906de572013-06-18 17:01:40 -07006068 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006069bool omx_vdec::release_input_done(void)
6070{
Arun Menon906de572013-06-18 17:01:40 -07006071 bool bRet = false;
6072 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006073
Arun Menon906de572013-06-18 17:01:40 -07006074 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6075 if (m_inp_mem_ptr) {
6076 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6077 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6078 break;
6079 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006080 }
Arun Menon906de572013-06-18 17:01:40 -07006081 if (j==drv_ctx.ip_buf.actualcount) {
6082 bRet = true;
6083 }
6084 } else {
6085 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006086 }
Arun Menon906de572013-06-18 17:01:40 -07006087 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006088}
6089
6090OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006091 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006092{
Arun Menon906de572013-06-18 17:01:40 -07006093 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6094 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) {
6095 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6096 return OMX_ErrorBadParameter;
6097 } else if (output_flush_progress) {
6098 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6099 buffer->nFilledLen = 0;
6100 buffer->nTimeStamp = 0;
6101 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6102 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6103 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006104 }
6105
Arun Menon906de572013-06-18 17:01:40 -07006106 if (m_debug_extradata) {
6107 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
6108 DEBUG_PRINT_HIGH("\n");
6109 DEBUG_PRINT_HIGH("***************************************************\n");
6110 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
6111 DEBUG_PRINT_HIGH("***************************************************\n");
6112 }
6113
6114 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
6115 DEBUG_PRINT_HIGH("\n");
6116 DEBUG_PRINT_HIGH("***************************************************\n");
6117 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
6118 DEBUG_PRINT_HIGH("***************************************************\n");
6119 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006120 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006121
6122
Arun Menon906de572013-06-18 17:01:40 -07006123 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6124 buffer, buffer->pBuffer);
6125 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006126
Arun Menon906de572013-06-18 17:01:40 -07006127 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6128 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6129 if (!output_flush_progress)
6130 post_event((unsigned)NULL, (unsigned)NULL,
6131 OMX_COMPONENT_GENERATE_EOS_DONE);
6132
6133 if (psource_frame) {
6134 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6135 psource_frame = NULL;
6136 }
6137 if (pdest_frame) {
6138 pdest_frame->nFilledLen = 0;
6139 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6140 (unsigned)NULL);
6141 pdest_frame = NULL;
6142 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006143 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006144
Arun Menon906de572013-06-18 17:01:40 -07006145 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006146 log_output_buffers(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006147
Arun Menon906de572013-06-18 17:01:40 -07006148 /* For use buffer we need to copy the data */
6149 if (!output_flush_progress) {
6150 /* This is the error check for non-recoverable errros */
6151 bool is_duplicate_ts_valid = true;
6152 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006153
Arun Menon906de572013-06-18 17:01:40 -07006154 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6155 output_capability == V4L2_PIX_FMT_MPEG2 ||
6156 output_capability == V4L2_PIX_FMT_DIVX ||
6157 output_capability == V4L2_PIX_FMT_DIVX_311)
6158 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006159
Arun Menon906de572013-06-18 17:01:40 -07006160 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6161 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6162 if (mbaff) {
6163 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306164 }
Arun Menon906de572013-06-18 17:01:40 -07006165 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306166
Arun Menon906de572013-06-18 17:01:40 -07006167 if (buffer->nFilledLen > 0) {
6168 time_stamp_dts.get_next_timestamp(buffer,
6169 is_interlaced && is_duplicate_ts_valid);
6170 if (m_debug_timestamp) {
6171 {
6172 OMX_TICKS expected_ts = 0;
6173 m_timestamp_list.pop_min_ts(expected_ts);
6174 if (is_interlaced && is_duplicate_ts_valid) {
6175 m_timestamp_list.pop_min_ts(expected_ts);
6176 }
6177 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6178 buffer->nTimeStamp, expected_ts);
6179
6180 if (buffer->nTimeStamp != expected_ts) {
6181 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6182 }
6183 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306184 }
Arun Menon906de572013-06-18 17:01:40 -07006185 } else {
6186 m_inp_err_count++;
6187 time_stamp_dts.remove_time_stamp(
6188 buffer->nTimeStamp,
6189 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306190 }
Arun Menon906de572013-06-18 17:01:40 -07006191
6192
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006193 }
Arun Menon906de572013-06-18 17:01:40 -07006194 if (m_cb.FillBufferDone) {
6195 if (buffer->nFilledLen > 0) {
6196 handle_extradata(buffer);
6197 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6198 set_frame_rate(buffer->nTimeStamp);
6199 else if (arbitrary_bytes)
6200 adjust_timestamp(buffer->nTimeStamp);
6201 if (perf_flag) {
6202 if (!proc_frms) {
6203 dec_time.stop();
6204 latency = dec_time.processing_time_us() - latency;
6205 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6206 dec_time.start();
6207 fps_metrics.start();
6208 }
6209 proc_frms++;
6210 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6211 OMX_U64 proc_time = 0;
6212 fps_metrics.stop();
6213 proc_time = fps_metrics.processing_time_us();
6214 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006215 proc_frms, (float)proc_time / 1e6,
6216 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006217 proc_frms = 0;
6218 }
6219 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006220
6221#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006222 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006223
Arun Menon906de572013-06-18 17:01:40 -07006224 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6225 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6226 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6227 buffer->nFilledLen + 3)&(~3));
6228 while (p_extra &&
6229 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
6230 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6231 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6232 if (p_extra->eType == OMX_ExtraDataNone) {
6233 break;
6234 }
6235 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6236 }
6237 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006238#endif
Arun Menon906de572013-06-18 17:01:40 -07006239 }
6240 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6241 prev_ts = LLONG_MAX;
6242 rst_prev_ts = true;
6243 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006244
Arun Menon906de572013-06-18 17:01:40 -07006245 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6246 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6247 buffer->pPlatformPrivate)->entryList->entry;
6248 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006249 OMX_BUFFERHEADERTYPE *il_buffer;
6250 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6251 if (il_buffer)
6252 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6253 else {
6254 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6255 return OMX_ErrorBadParameter;
6256 }
6257 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
6258 } else {
6259 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006260 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006261
Arun Menon906de572013-06-18 17:01:40 -07006262 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006263}
6264
6265OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006266 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006267{
6268
Arun Menon906de572013-06-18 17:01:40 -07006269 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006270 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006271 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006272 }
6273
6274 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006275 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006276 pending_input_buffers--;
6277
Arun Menon906de572013-06-18 17:01:40 -07006278 if (arbitrary_bytes) {
6279 if (pdest_frame == NULL && input_flush_progress == false) {
6280 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6281 pdest_frame = buffer;
6282 buffer->nFilledLen = 0;
6283 buffer->nTimeStamp = LLONG_MAX;
6284 push_input_buffer (hComp);
6285 } else {
6286 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6287 buffer->nFilledLen = 0;
6288 if (!m_input_free_q.insert_entry((unsigned)buffer,
6289 (unsigned)NULL, (unsigned)NULL)) {
6290 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6291 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006292 }
Arun Menon906de572013-06-18 17:01:40 -07006293 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006294 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006295 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006296 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6297 }
6298 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6299 }
6300 return OMX_ErrorNone;
6301}
6302
Shalaj Jain273b3e02012-06-22 19:08:03 -07006303int omx_vdec::async_message_process (void *context, void* message)
6304{
Arun Menon906de572013-06-18 17:01:40 -07006305 omx_vdec* omx = NULL;
6306 struct vdec_msginfo *vdec_msg = NULL;
6307 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6308 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6309 struct vdec_output_frameinfo *output_respbuf = NULL;
6310 int rc=1;
6311 if (context == NULL || message == NULL) {
6312 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6313 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006314 }
Arun Menon906de572013-06-18 17:01:40 -07006315 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006316
Arun Menon906de572013-06-18 17:01:40 -07006317 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006318
Arun Menon906de572013-06-18 17:01:40 -07006319 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006320
Arun Menon906de572013-06-18 17:01:40 -07006321 case VDEC_MSG_EVT_HW_ERROR:
6322 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6323 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6324 break;
6325
6326 case VDEC_MSG_RESP_START_DONE:
6327 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6328 OMX_COMPONENT_GENERATE_START_DONE);
6329 break;
6330
6331 case VDEC_MSG_RESP_STOP_DONE:
6332 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6333 OMX_COMPONENT_GENERATE_STOP_DONE);
6334 break;
6335
6336 case VDEC_MSG_RESP_RESUME_DONE:
6337 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6338 OMX_COMPONENT_GENERATE_RESUME_DONE);
6339 break;
6340
6341 case VDEC_MSG_RESP_PAUSE_DONE:
6342 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6343 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6344 break;
6345
6346 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6347 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6348 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6349 break;
6350 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6351 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6352 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6353 break;
6354 case VDEC_MSG_RESP_INPUT_FLUSHED:
6355 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6356
6357 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6358 vdec_msg->msgdata.input_frame_clientdata; */
6359
6360 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6361 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6362 if (omxhdr == NULL ||
6363 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) {
6364 omxhdr = NULL;
6365 vdec_msg->status_code = VDEC_S_EFATAL;
6366 }
6367 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6368 DEBUG_PRINT_HIGH("Unsupported input");
6369 omx->omx_report_error ();
6370 }
6371 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6372 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6373 }
6374 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6375 OMX_COMPONENT_GENERATE_EBD);
6376 break;
6377 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6378 int64_t *timestamp;
6379 timestamp = (int64_t *) malloc(sizeof(int64_t));
6380 if (timestamp) {
6381 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6382 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6383 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6384 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6385 vdec_msg->msgdata.output_frame.time_stamp);
6386 }
6387 break;
6388 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6389 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6390
6391 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6392 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6393 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6394 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6395 vdec_msg->msgdata.output_frame.pic_type);
6396
6397 if (omxhdr && omxhdr->pOutputPortPrivate &&
6398 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6399 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6400 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) {
6401 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6402 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6403 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6404 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6405 omxhdr->nFlags = 0;
6406
6407 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS) {
6408 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6409 //rc = -1;
6410 }
6411 if (omxhdr->nFilledLen) {
6412 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6413 }
6414 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6415 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6416 } else {
6417 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6418 }
6419 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6420 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6421 }
6422 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6423 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6424 }
6425 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6426 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
6427 !(v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006428 omx->time_stamp_dts.remove_time_stamp(
6429 omxhdr->nTimeStamp,
6430 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6431 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006432 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6433 OMX_COMPONENT_GENERATE_FTB);
6434 break;
6435 }
6436 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6437 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6438 }
6439 vdec_msg->msgdata.output_frame.bufferaddr =
6440 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6441 int format_notably_changed = 0;
6442 if (omxhdr->nFilledLen &&
6443 (omxhdr->nFilledLen != omx->prev_n_filled_len)) {
6444 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6445 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6446 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
6447 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6448 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6449 format_notably_changed = 1;
6450 }
6451 }
6452 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6453 vdec_msg->msgdata.output_frame.framesize.left)
6454 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6455 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6456 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6457 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6458 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6459 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6460 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6461 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
6462 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6463 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6464 }
6465 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
6466 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6467 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006468 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6469 omx->drv_ctx.video_resolution.frame_width) {
6470 vdec_msg->msgdata.output_frame.framesize.left = 0;
6471 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6472 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6473 }
6474 }
6475 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6476 omx->drv_ctx.video_resolution.frame_height) {
6477 vdec_msg->msgdata.output_frame.framesize.top = 0;
6478 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6479 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6480 }
6481 }
6482 DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d\n",
6483 vdec_msg->msgdata.output_frame.framesize.left,
6484 vdec_msg->msgdata.output_frame.framesize.top,
6485 vdec_msg->msgdata.output_frame.framesize.right,
6486 vdec_msg->msgdata.output_frame.framesize.bottom,
6487 omx->drv_ctx.video_resolution.frame_width,
6488 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006489 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6490 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6491 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6492 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6493 format_notably_changed = 1;
6494 }
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006495 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d\n",
6496 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6497 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006498 if (format_notably_changed) {
6499 if (omx->is_video_session_supported()) {
6500 omx->post_event (NULL, vdec_msg->status_code,
6501 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6502 } else {
6503 if (!omx->client_buffers.update_buffer_req()) {
6504 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6505 }
6506 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6507 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6508 }
6509 }
6510 if (omxhdr->nFilledLen)
6511 omx->prev_n_filled_len = omxhdr->nFilledLen;
6512
6513 output_respbuf = (struct vdec_output_frameinfo *)\
6514 omxhdr->pOutputPortPrivate;
6515 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6516 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6517 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6518 output_respbuf->pic_type = PICTURE_TYPE_I;
6519 }
6520 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6521 output_respbuf->pic_type = PICTURE_TYPE_P;
6522 }
6523 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6524 output_respbuf->pic_type = PICTURE_TYPE_B;
6525 }
6526
6527 if (omx->output_use_buffer)
6528 memcpy ( omxhdr->pBuffer, (void *)
6529 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6530 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6531 vdec_msg->msgdata.output_frame.len);
6532 } else
6533 omxhdr->nFilledLen = 0;
6534 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6535 OMX_COMPONENT_GENERATE_FBD);
6536 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6537 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6538 OMX_COMPONENT_GENERATE_EOS_DONE);
6539 else
6540 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6541 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6542 break;
6543 case VDEC_MSG_EVT_CONFIG_CHANGED:
6544 DEBUG_PRINT_HIGH("\n Port settings changed");
6545 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6546 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6547 break;
6548 default:
6549 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006550 }
Arun Menon906de572013-06-18 17:01:40 -07006551 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006552}
6553
6554OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006555 OMX_HANDLETYPE hComp,
6556 OMX_BUFFERHEADERTYPE *buffer
6557 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006558{
Arun Menon906de572013-06-18 17:01:40 -07006559 unsigned address,p2,id;
6560 DEBUG_PRINT_LOW("\n Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006561
Arun Menon906de572013-06-18 17:01:40 -07006562 if (buffer == NULL) {
6563 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006564 }
Arun Menon906de572013-06-18 17:01:40 -07006565 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6566 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
6567 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6568
6569 /* return zero length and not an EOS buffer */
6570 /* return buffer if input flush in progress */
6571 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6572 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
6573 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
6574 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6575 return OMX_ErrorNone;
6576 }
6577
6578 if (psource_frame == NULL) {
6579 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
6580 psource_frame = buffer;
6581 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
6582 push_input_buffer (hComp);
6583 } else {
6584 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
6585 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6586 (unsigned)NULL)) {
6587 return OMX_ErrorBadParameter;
6588 }
6589 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006590
6591
Arun Menon906de572013-06-18 17:01:40 -07006592 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006593}
6594
6595OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6596{
Arun Menon906de572013-06-18 17:01:40 -07006597 unsigned address,p2,id;
6598 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006599
Arun Menon906de572013-06-18 17:01:40 -07006600 if (pdest_frame == NULL || psource_frame == NULL) {
6601 /*Check if we have a destination buffer*/
6602 if (pdest_frame == NULL) {
6603 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
6604 if (m_input_free_q.m_size) {
6605 m_input_free_q.pop_entry(&address,&p2,&id);
6606 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6607 pdest_frame->nFilledLen = 0;
6608 pdest_frame->nTimeStamp = LLONG_MAX;
6609 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
6610 }
6611 }
6612
6613 /*Check if we have a destination buffer*/
6614 if (psource_frame == NULL) {
6615 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
6616 if (m_input_pending_q.m_size) {
6617 m_input_pending_q.pop_entry(&address,&p2,&id);
6618 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
6619 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6620 psource_frame->nTimeStamp);
6621 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6622 psource_frame->nFlags,psource_frame->nFilledLen);
6623
6624 }
6625 }
6626
Shalaj Jain273b3e02012-06-22 19:08:03 -07006627 }
6628
Arun Menon906de572013-06-18 17:01:40 -07006629 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6630 switch (codec_type_parse) {
6631 case CODEC_TYPE_MPEG4:
6632 case CODEC_TYPE_H263:
6633 case CODEC_TYPE_MPEG2:
6634 ret = push_input_sc_codec(hComp);
6635 break;
6636 case CODEC_TYPE_H264:
6637 ret = push_input_h264(hComp);
6638 break;
6639 case CODEC_TYPE_VC1:
6640 ret = push_input_vc1(hComp);
6641 break;
6642 default:
6643 break;
6644 }
6645 if (ret != OMX_ErrorNone) {
6646 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
6647 omx_report_error ();
6648 break;
6649 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006650 }
6651
Arun Menon906de572013-06-18 17:01:40 -07006652 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006653}
6654
6655OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
6656{
Arun Menon906de572013-06-18 17:01:40 -07006657 OMX_U32 partial_frame = 1;
6658 OMX_BOOL generate_ebd = OMX_TRUE;
6659 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006660
Arun Menon906de572013-06-18 17:01:40 -07006661 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
6662 psource_frame,psource_frame->nTimeStamp);
6663 if (m_frame_parser.parse_sc_frame(psource_frame,
6664 pdest_frame,&partial_frame) == -1) {
6665 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
6666 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006667 }
Arun Menon906de572013-06-18 17:01:40 -07006668
6669 if (partial_frame == 0) {
6670 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
6671 pdest_frame->nFilledLen,psource_frame,frame_count);
6672
6673
6674 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
6675 /*First Parsed buffer will have only header Hence skip*/
6676 if (frame_count == 0) {
6677 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
6678
6679 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
6680 codec_type_parse == CODEC_TYPE_DIVX) {
6681 mp4StreamType psBits;
6682 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
6683 psBits.numBytes = pdest_frame->nFilledLen;
6684 mp4_headerparser.parseHeader(&psBits);
6685 }
6686
6687 frame_count++;
6688 } else {
6689 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6690 if (pdest_frame->nFilledLen) {
6691 /*Push the frame to the Decoder*/
6692 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6693 return OMX_ErrorBadParameter;
6694 }
6695 frame_count++;
6696 pdest_frame = NULL;
6697
6698 if (m_input_free_q.m_size) {
6699 m_input_free_q.pop_entry(&address,&p2,&id);
6700 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6701 pdest_frame->nFilledLen = 0;
6702 }
6703 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
6704 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
6705 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
6706 (unsigned)NULL);
6707 pdest_frame = NULL;
6708 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006709 }
Arun Menon906de572013-06-18 17:01:40 -07006710 } else {
6711 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
6712 /*Check if Destination Buffer is full*/
6713 if (pdest_frame->nAllocLen ==
6714 pdest_frame->nFilledLen + pdest_frame->nOffset) {
6715 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
6716 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006717 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006718 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006719
Arun Menon906de572013-06-18 17:01:40 -07006720 if (psource_frame->nFilledLen == 0) {
6721 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6722 if (pdest_frame) {
6723 pdest_frame->nFlags |= psource_frame->nFlags;
6724 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
6725 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6726 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6727 pdest_frame->nFilledLen,frame_count++);
6728 /*Push the frame to the Decoder*/
6729 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6730 return OMX_ErrorBadParameter;
6731 }
6732 frame_count++;
6733 pdest_frame = NULL;
6734 } else {
6735 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
6736 generate_ebd = OMX_FALSE;
6737 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006738 }
Arun Menon906de572013-06-18 17:01:40 -07006739 if (generate_ebd) {
6740 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
6741 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6742 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006743
Arun Menon906de572013-06-18 17:01:40 -07006744 if (m_input_pending_q.m_size) {
6745 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6746 m_input_pending_q.pop_entry(&address,&p2,&id);
6747 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6748 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6749 psource_frame->nTimeStamp);
6750 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6751 psource_frame->nFlags,psource_frame->nFilledLen);
6752 }
6753 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006754 }
Arun Menon906de572013-06-18 17:01:40 -07006755 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006756}
6757
6758OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
6759{
Arun Menon906de572013-06-18 17:01:40 -07006760 OMX_U32 partial_frame = 1;
6761 unsigned address = 0, p2 = 0, id = 0;
6762 OMX_BOOL isNewFrame = OMX_FALSE;
6763 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006764
Arun Menon906de572013-06-18 17:01:40 -07006765 if (h264_scratch.pBuffer == NULL) {
6766 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
6767 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006768 }
Arun Menon906de572013-06-18 17:01:40 -07006769 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
6770 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
6771 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
6772 if (h264_scratch.nFilledLen && look_ahead_nal) {
6773 look_ahead_nal = false;
6774 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6775 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006776 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6777 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6778 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Arun Menon906de572013-06-18 17:01:40 -07006779 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006780 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006781 } else {
6782 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006783 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006784 }
Arun Menon906de572013-06-18 17:01:40 -07006785 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07006786
6787 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
6788 in EOS flag getting associated with the destination
6789 */
6790 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
6791 pdest_frame->nFilledLen) {
6792 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
6793 generate_ebd = OMX_FALSE;
6794 }
6795
Arun Menon906de572013-06-18 17:01:40 -07006796 if (nal_length == 0) {
6797 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
6798 if (m_frame_parser.parse_sc_frame(psource_frame,
6799 &h264_scratch,&partial_frame) == -1) {
6800 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006801 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006802 }
Arun Menon906de572013-06-18 17:01:40 -07006803 } else {
6804 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
6805 if (m_frame_parser.parse_h264_nallength(psource_frame,
6806 &h264_scratch,&partial_frame) == -1) {
6807 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
6808 return OMX_ErrorBadParameter;
6809 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006810 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006811
Arun Menon906de572013-06-18 17:01:40 -07006812 if (partial_frame == 0) {
6813 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
6814 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
6815 nal_count++;
6816 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
6817 h264_scratch.nFlags = psource_frame->nFlags;
6818 } else {
6819 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
6820 if (h264_scratch.nFilledLen) {
6821 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
6822 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006823#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07006824 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6825 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
6826 h264_scratch.nFilledLen, NALU_TYPE_SEI);
6827 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
6828 // If timeinfo is present frame info from SEI is already processed
6829 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
6830 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006831#endif
Arun Menon906de572013-06-18 17:01:40 -07006832 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
6833 nal_count++;
6834 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
6835 pdest_frame->nTimeStamp = h264_last_au_ts;
6836 pdest_frame->nFlags = h264_last_au_flags;
6837#ifdef PANSCAN_HDLR
6838 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
6839 h264_parser->update_panscan_data(h264_last_au_ts);
6840#endif
6841 }
6842 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
6843 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
6844 h264_last_au_ts = h264_scratch.nTimeStamp;
6845 h264_last_au_flags = h264_scratch.nFlags;
6846#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
6847 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
6848 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
6849 if (!VALID_TS(h264_last_au_ts))
6850 h264_last_au_ts = ts_in_sei;
6851 }
6852#endif
6853 } else
6854 h264_last_au_ts = LLONG_MAX;
6855 }
6856
6857 if (!isNewFrame) {
6858 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6859 h264_scratch.nFilledLen) {
6860 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
6861 h264_scratch.nFilledLen);
6862 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6863 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6864 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6865 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
6866 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6867 h264_scratch.nFilledLen = 0;
6868 } else {
6869 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
6870 return OMX_ErrorBadParameter;
6871 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07006872 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07006873 look_ahead_nal = true;
6874 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
6875 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6876 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6877 pdest_frame->nFilledLen,frame_count++);
6878
6879 if (pdest_frame->nFilledLen == 0) {
6880 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
6881 look_ahead_nal = false;
6882 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6883 h264_scratch.nFilledLen) {
6884 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6885 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6886 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6887 h264_scratch.nFilledLen = 0;
6888 } else {
6889 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
6890 return OMX_ErrorBadParameter;
6891 }
6892 } else {
6893 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
6894 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
6895 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6896 }
6897 /*Push the frame to the Decoder*/
6898 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6899 return OMX_ErrorBadParameter;
6900 }
6901 //frame_count++;
6902 pdest_frame = NULL;
6903 if (m_input_free_q.m_size) {
6904 m_input_free_q.pop_entry(&address,&p2,&id);
6905 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6906 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
6907 pdest_frame->nFilledLen = 0;
6908 pdest_frame->nFlags = 0;
6909 pdest_frame->nTimeStamp = LLONG_MAX;
6910 }
6911 }
6912 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006913 }
Arun Menon906de572013-06-18 17:01:40 -07006914 } else {
6915 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
6916 /*Check if Destination Buffer is full*/
6917 if (h264_scratch.nAllocLen ==
6918 h264_scratch.nFilledLen + h264_scratch.nOffset) {
6919 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
6920 return OMX_ErrorStreamCorrupt;
6921 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006922 }
Arun Menon906de572013-06-18 17:01:40 -07006923
6924 if (!psource_frame->nFilledLen) {
6925 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
6926
6927 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6928 if (pdest_frame) {
6929 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
6930 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6931 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07006932 if(pdest_frame->nFilledLen == 0) {
6933 /* No residual frame from before, send whatever
6934 * we have left */
6935 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6936 h264_scratch.pBuffer, h264_scratch.nFilledLen);
6937 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6938 h264_scratch.nFilledLen = 0;
6939 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
6940 } else {
6941 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
6942 if(!isNewFrame) {
6943 /* Have a residual frame, but we know that the
6944 * AU in this frame is belonging to whatever
6945 * frame we had left over. So append it */
6946 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6947 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6948 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6949 h264_scratch.nFilledLen = 0;
6950 pdest_frame->nTimeStamp = h264_last_au_ts;
6951 } else {
6952 /* Completely new frame, let's just push what
6953 * we have now. The resulting EBD would trigger
6954 * another push */
6955 generate_ebd = OMX_FALSE;
6956 pdest_frame->nTimeStamp = h264_last_au_ts;
6957 h264_last_au_ts = h264_scratch.nTimeStamp;
6958 }
6959 }
Arun Menon906de572013-06-18 17:01:40 -07006960 } else {
6961 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
6962 return OMX_ErrorBadParameter;
6963 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07006964
6965 /* Iff we coalesced two buffers, inherit the flags of both bufs */
6966 if(generate_ebd == OMX_TRUE) {
6967 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
6968 }
Arun Menon906de572013-06-18 17:01:40 -07006969
6970 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
6971 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6972 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
6973#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
6974 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
6975 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
6976 if (!VALID_TS(pdest_frame->nTimeStamp))
6977 pdest_frame->nTimeStamp = ts_in_sei;
6978 }
6979#endif
6980 /*Push the frame to the Decoder*/
6981 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6982 return OMX_ErrorBadParameter;
6983 }
6984 frame_count++;
6985 pdest_frame = NULL;
6986 } else {
6987 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
6988 pdest_frame,h264_scratch.nFilledLen);
6989 generate_ebd = OMX_FALSE;
6990 }
6991 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006992 }
Arun Menon906de572013-06-18 17:01:40 -07006993 if (generate_ebd && !psource_frame->nFilledLen) {
6994 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6995 psource_frame = NULL;
6996 if (m_input_pending_q.m_size) {
6997 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6998 m_input_pending_q.pop_entry(&address,&p2,&id);
6999 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7000 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
7001 psource_frame->nFlags,psource_frame->nFilledLen);
7002 }
7003 }
7004 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007005}
7006
7007OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7008{
7009 OMX_U8 *buf, *pdest;
7010 OMX_U32 partial_frame = 1;
7011 OMX_U32 buf_len, dest_len;
7012
Arun Menon906de572013-06-18 17:01:40 -07007013 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007014 first_frame = 1;
7015 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
Arun Menon906de572013-06-18 17:01:40 -07007016 if (!m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007017 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7018 buf = psource_frame->pBuffer;
7019 buf_len = psource_frame->nFilledLen;
7020
7021 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007022 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007023 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007024 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007025 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007026 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007027 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7028 return OMX_ErrorStreamCorrupt;
7029 }
Arun Menon906de572013-06-18 17:01:40 -07007030 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007031 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7032 pdest_frame->nOffset;
7033 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007034 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007035
Arun Menon906de572013-06-18 17:01:40 -07007036 if (dest_len < m_vendor_config.nDataSize) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007037 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7038 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007039 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007040 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7041 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7042 }
7043 }
7044 }
7045
Arun Menon906de572013-06-18 17:01:40 -07007046 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007047 case VC1_AP:
7048 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007049 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007050 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7051 return OMX_ErrorBadParameter;
7052 }
Arun Menon906de572013-06-18 17:01:40 -07007053 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007054
7055 case VC1_SP_MP_RCV:
7056 default:
7057 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7058 return OMX_ErrorBadParameter;
7059 }
7060 return OMX_ErrorNone;
7061}
7062
David Ng38e2d232013-03-15 20:05:58 -07007063#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007064bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007065 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007066{
Arun Menon906de572013-06-18 17:01:40 -07007067 struct pmem_allocation allocation;
7068 allocation.size = buffer_size;
7069 allocation.align = clip2(alignment);
7070 if (allocation.align < 4096) {
7071 allocation.align = 4096;
7072 }
7073 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
7074 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7075 allocation.align, allocation.size);
7076 return false;
7077 }
7078 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007079}
David Ng38e2d232013-03-15 20:05:58 -07007080#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007081#ifdef USE_ION
7082int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007083 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7084 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007085{
Arun Menon906de572013-06-18 17:01:40 -07007086 int fd = -EINVAL;
7087 int rc = -EINVAL;
7088 int ion_dev_flag;
7089 struct vdec_ion ion_buf_info;
7090 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7091 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7092 return -EINVAL;
7093 }
7094 ion_dev_flag = O_RDONLY;
7095 fd = open (MEM_DEVICE, ion_dev_flag);
7096 if (fd < 0) {
7097 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7098 return fd;
7099 }
7100 alloc_data->flags = 0;
7101 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7102 alloc_data->flags |= ION_FLAG_CACHED;
7103 }
7104 alloc_data->len = buffer_size;
7105 alloc_data->align = clip2(alignment);
7106 if (alloc_data->align < 4096) {
7107 alloc_data->align = 4096;
7108 }
7109 if ((secure_mode) && (flag & ION_SECURE))
7110 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007111
Arun Menon906de572013-06-18 17:01:40 -07007112 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7113 if (secure_mode)
7114 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7115 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7116 if (rc || !alloc_data->handle) {
7117 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7118 alloc_data->handle = NULL;
7119 close(fd);
7120 fd = -ENOMEM;
7121 return fd;
7122 }
7123 fd_data->handle = alloc_data->handle;
7124 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7125 if (rc) {
7126 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7127 ion_buf_info.ion_alloc_data = *alloc_data;
7128 ion_buf_info.ion_device_fd = fd;
7129 ion_buf_info.fd_ion_data = *fd_data;
7130 free_ion_memory(&ion_buf_info);
7131 fd_data->fd =-1;
7132 close(fd);
7133 fd = -ENOMEM;
7134 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007135
Arun Menon906de572013-06-18 17:01:40 -07007136 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007137}
7138
Arun Menon906de572013-06-18 17:01:40 -07007139void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7140{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007141
Arun Menon906de572013-06-18 17:01:40 -07007142 if (!buf_ion_info) {
7143 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7144 return;
7145 }
7146 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7147 &buf_ion_info->ion_alloc_data.handle)) {
7148 DEBUG_PRINT_ERROR("\n ION: free failed" );
7149 }
7150 close(buf_ion_info->ion_device_fd);
7151 buf_ion_info->ion_device_fd = -1;
7152 buf_ion_info->ion_alloc_data.handle = NULL;
7153 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007154}
7155#endif
7156void omx_vdec::free_output_buffer_header()
7157{
Arun Menon906de572013-06-18 17:01:40 -07007158 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7159 output_use_buffer = false;
7160 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007161
Arun Menon906de572013-06-18 17:01:40 -07007162 if (m_out_mem_ptr) {
7163 free (m_out_mem_ptr);
7164 m_out_mem_ptr = NULL;
7165 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007166
Arun Menon906de572013-06-18 17:01:40 -07007167 if (m_platform_list) {
7168 free(m_platform_list);
7169 m_platform_list = NULL;
7170 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007171
Arun Menon906de572013-06-18 17:01:40 -07007172 if (drv_ctx.ptr_respbuffer) {
7173 free (drv_ctx.ptr_respbuffer);
7174 drv_ctx.ptr_respbuffer = NULL;
7175 }
7176 if (drv_ctx.ptr_outputbuffer) {
7177 free (drv_ctx.ptr_outputbuffer);
7178 drv_ctx.ptr_outputbuffer = NULL;
7179 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007180#ifdef USE_ION
7181 if (drv_ctx.op_buf_ion_info) {
7182 DEBUG_PRINT_LOW("\n Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007183 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007184 drv_ctx.op_buf_ion_info = NULL;
7185 }
7186#endif
7187}
7188
7189void omx_vdec::free_input_buffer_header()
7190{
7191 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007192 if (arbitrary_bytes) {
7193 if (m_frame_parser.mutils) {
7194 DEBUG_PRINT_LOW("\n Free utils parser");
7195 delete (m_frame_parser.mutils);
7196 m_frame_parser.mutils = NULL;
7197 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007198
Arun Menon906de572013-06-18 17:01:40 -07007199 if (m_inp_heap_ptr) {
7200 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7201 free (m_inp_heap_ptr);
7202 m_inp_heap_ptr = NULL;
7203 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007204
Arun Menon906de572013-06-18 17:01:40 -07007205 if (m_phdr_pmem_ptr) {
7206 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7207 free (m_phdr_pmem_ptr);
7208 m_phdr_pmem_ptr = NULL;
7209 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007210 }
Arun Menon906de572013-06-18 17:01:40 -07007211 if (m_inp_mem_ptr) {
7212 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7213 free (m_inp_mem_ptr);
7214 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007215 }
Arun Menon906de572013-06-18 17:01:40 -07007216 if (drv_ctx.ptr_inputbuffer) {
7217 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7218 free (drv_ctx.ptr_inputbuffer);
7219 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007220 }
7221#ifdef USE_ION
7222 if (drv_ctx.ip_buf_ion_info) {
7223 DEBUG_PRINT_LOW("\n Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007224 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007225 drv_ctx.ip_buf_ion_info = NULL;
7226 }
7227#endif
7228}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007229
7230int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007231{
Arun Menon906de572013-06-18 17:01:40 -07007232 enum v4l2_buf_type btype;
7233 int rc = 0;
7234 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007235
Arun Menon906de572013-06-18 17:01:40 -07007236 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7237 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7238 v4l2_port = OUTPUT_PORT;
7239 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7240 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7241 v4l2_port = CAPTURE_PORT;
7242 } else if (port == OMX_ALL) {
7243 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7244 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007245
Arun Menon906de572013-06-18 17:01:40 -07007246 if (!rc_input)
7247 return rc_input;
7248 else
7249 return rc_output;
7250 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007251
Arun Menon906de572013-06-18 17:01:40 -07007252 if (!streaming[v4l2_port]) {
7253 // already streamed off, warn and move on
7254 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7255 " which is already streamed off", v4l2_port);
7256 return 0;
7257 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007258
Arun Menon906de572013-06-18 17:01:40 -07007259 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007260
Arun Menon906de572013-06-18 17:01:40 -07007261 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7262 if (rc) {
7263 /*TODO: How to handle this case */
7264 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
7265 } else {
7266 streaming[v4l2_port] = false;
7267 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007268
Arun Menon906de572013-06-18 17:01:40 -07007269 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007270}
7271
7272OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7273{
Arun Menon906de572013-06-18 17:01:40 -07007274 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7275 struct v4l2_requestbuffers bufreq;
7276 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7277 struct v4l2_format fmt;
7278 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007279 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007280 buffer_prop->actualcount, buffer_prop->buffer_size);
7281 bufreq.memory = V4L2_MEMORY_USERPTR;
7282 bufreq.count = 1;
7283 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7284 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7285 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7286 fmt.fmt.pix_mp.pixelformat = output_capability;
7287 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7288 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7289 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7290 fmt.fmt.pix_mp.pixelformat = capture_capability;
7291 } else {
7292 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007293 }
Arun Menon906de572013-06-18 17:01:40 -07007294 if (eRet==OMX_ErrorNone) {
7295 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007296 }
Arun Menon906de572013-06-18 17:01:40 -07007297 if (ret) {
7298 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7299 /*TODO: How to handle this case */
7300 eRet = OMX_ErrorInsufficientResources;
7301 return eRet;
7302 } else {
7303 buffer_prop->actualcount = bufreq.count;
7304 buffer_prop->mincount = bufreq.count;
7305 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007306 }
Arun Menon906de572013-06-18 17:01:40 -07007307 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7308 buffer_prop->actualcount, buffer_prop->buffer_size);
7309
7310 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7311 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7312
7313 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7314
7315 update_resolution(fmt.fmt.pix_mp.width,
7316 fmt.fmt.pix_mp.height,
7317 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7318 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7319 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7320 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
7321 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
7322
7323 if (ret) {
7324 /*TODO: How to handle this case */
7325 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7326 eRet = OMX_ErrorInsufficientResources;
7327 } else {
7328 int extra_idx = 0;
7329
7330 eRet = is_video_session_supported();
7331 if (eRet)
7332 return eRet;
7333
7334 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7335 buf_size = buffer_prop->buffer_size;
7336 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7337 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7338 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7339 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7340 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7341 return OMX_ErrorBadParameter;
7342 }
7343 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7344 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7345 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7346 }
7347 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7348 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7349 }
7350 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7351 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7352 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7353 client_extra_data_size);
7354 }
7355 if (client_extra_data_size) {
7356 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7357 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7358 }
7359 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7360 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7361 drv_ctx.extradata_info.buffer_size = extra_data_size;
7362 buf_size += client_extra_data_size;
7363 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7364 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7365 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7366 if (in_reconfig) // BufReq will be set to driver when port is disabled
7367 buffer_prop->buffer_size = buf_size;
7368 else if (buf_size != buffer_prop->buffer_size) {
7369 buffer_prop->buffer_size = buf_size;
7370 eRet = set_buffer_req(buffer_prop);
7371 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007372 }
Arun Menon906de572013-06-18 17:01:40 -07007373 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7374 buffer_prop->actualcount, buffer_prop->buffer_size);
7375 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007376}
7377
7378OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7379{
Arun Menon906de572013-06-18 17:01:40 -07007380 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7381 unsigned buf_size = 0;
7382 struct v4l2_format fmt;
7383 struct v4l2_requestbuffers bufreq;
7384 int ret;
7385 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7386 buffer_prop->actualcount, buffer_prop->buffer_size);
7387 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7388 if (buf_size != buffer_prop->buffer_size) {
7389 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7390 buffer_prop->buffer_size, buf_size);
7391 eRet = OMX_ErrorBadParameter;
7392 } else {
7393 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7394 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007395
Arun Menon906de572013-06-18 17:01:40 -07007396 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7397 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7398 fmt.fmt.pix_mp.pixelformat = output_capability;
7399 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7400 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7401 fmt.fmt.pix_mp.pixelformat = capture_capability;
7402 } else {
7403 eRet = OMX_ErrorBadParameter;
7404 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007405
Arun Menon906de572013-06-18 17:01:40 -07007406 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7407 if (ret) {
7408 /*TODO: How to handle this case */
7409 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7410 eRet = OMX_ErrorInsufficientResources;
7411 }
7412
7413 bufreq.memory = V4L2_MEMORY_USERPTR;
7414 bufreq.count = buffer_prop->actualcount;
7415 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7416 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7417 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7418 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7419 } else {
7420 eRet = OMX_ErrorBadParameter;
7421 }
7422
7423 if (eRet==OMX_ErrorNone) {
7424 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7425 }
7426
7427 if (ret) {
7428 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7429 /*TODO: How to handle this case */
7430 eRet = OMX_ErrorInsufficientResources;
7431 } else if (bufreq.count < buffer_prop->actualcount) {
7432 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7433 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7434 buffer_prop->actualcount, bufreq.count);
7435 eRet = OMX_ErrorInsufficientResources;
7436 } else {
7437 if (!client_buffers.update_buffer_req()) {
7438 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7439 eRet = OMX_ErrorInsufficientResources;
7440 }
7441 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007442 }
Arun Menon906de572013-06-18 17:01:40 -07007443 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007444}
7445
Shalaj Jain273b3e02012-06-22 19:08:03 -07007446OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7447{
Arun Menon906de572013-06-18 17:01:40 -07007448 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7449 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007450}
7451
7452OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7453{
Arun Menon906de572013-06-18 17:01:40 -07007454 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7455 if (!portDefn) {
7456 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007457 }
Arun Menon906de572013-06-18 17:01:40 -07007458 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
7459 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7460 portDefn->nSize = sizeof(portDefn);
7461 portDefn->eDomain = OMX_PortDomainVideo;
7462 if (drv_ctx.frame_rate.fps_denominator > 0)
7463 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7464 drv_ctx.frame_rate.fps_denominator;
7465 else {
7466 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7467 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007468 }
Arun Menon906de572013-06-18 17:01:40 -07007469 if (0 == portDefn->nPortIndex) {
7470 portDefn->eDir = OMX_DirInput;
7471 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7472 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7473 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7474 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7475 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7476 portDefn->bEnabled = m_inp_bEnabled;
7477 portDefn->bPopulated = m_inp_bPopulated;
7478 } else if (1 == portDefn->nPortIndex) {
7479 unsigned int buf_size = 0;
7480 if (!client_buffers.update_buffer_req()) {
7481 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
7482 return OMX_ErrorHardware;
7483 }
7484 if (!client_buffers.get_buffer_req(buf_size)) {
7485 DEBUG_PRINT_ERROR("\n update buffer requirements");
7486 return OMX_ErrorHardware;
7487 }
7488 portDefn->nBufferSize = buf_size;
7489 portDefn->eDir = OMX_DirOutput;
7490 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7491 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7492 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7493 portDefn->bEnabled = m_out_bEnabled;
7494 portDefn->bPopulated = m_out_bPopulated;
7495 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
7496 DEBUG_PRINT_ERROR("\n Error in getting color format");
7497 return OMX_ErrorHardware;
7498 }
7499 } else {
7500 portDefn->eDir = OMX_DirMax;
7501 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7502 (int)portDefn->nPortIndex);
7503 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007504 }
Arun Menon906de572013-06-18 17:01:40 -07007505 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7506 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7507 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7508 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7509 DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
7510 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
7511 portDefn->format.video.nFrameHeight,
7512 portDefn->format.video.nStride,
7513 portDefn->format.video.nSliceHeight);
7514 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007515
7516}
7517
7518OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7519{
Arun Menon906de572013-06-18 17:01:40 -07007520 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7521 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7522 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007523
Arun Menon906de572013-06-18 17:01:40 -07007524 if (!m_out_mem_ptr) {
7525 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
7526 int nBufHdrSize = 0;
7527 int nPlatformEntrySize = 0;
7528 int nPlatformListSize = 0;
7529 int nPMEMInfoSize = 0;
7530 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7531 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7532 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007533
Arun Menon906de572013-06-18 17:01:40 -07007534 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
7535 drv_ctx.op_buf.actualcount);
7536 nBufHdrSize = drv_ctx.op_buf.actualcount *
7537 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007538
Arun Menon906de572013-06-18 17:01:40 -07007539 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7540 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7541 nPlatformListSize = drv_ctx.op_buf.actualcount *
7542 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7543 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7544 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007545
Arun Menon906de572013-06-18 17:01:40 -07007546 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
7547 sizeof(OMX_BUFFERHEADERTYPE),
7548 nPMEMInfoSize,
7549 nPlatformListSize);
7550 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
7551 m_out_bm_count);
7552 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7553 // Alloc mem for platform specific info
7554 char *pPtr=NULL;
7555 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7556 nPMEMInfoSize,1);
7557 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7558 calloc (sizeof(struct vdec_bufferpayload),
7559 drv_ctx.op_buf.actualcount);
7560 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7561 calloc (sizeof (struct vdec_output_frameinfo),
7562 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007563#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007564 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7565 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007566#endif
7567
Arun Menon906de572013-06-18 17:01:40 -07007568 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7569 && drv_ctx.ptr_respbuffer) {
7570 bufHdr = m_out_mem_ptr;
7571 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7572 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7573 (((char *) m_platform_list) + nPlatformListSize);
7574 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7575 (((char *) m_platform_entry) + nPlatformEntrySize);
7576 pPlatformList = m_platform_list;
7577 pPlatformEntry = m_platform_entry;
7578 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007579
Arun Menon906de572013-06-18 17:01:40 -07007580 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007581
Arun Menon906de572013-06-18 17:01:40 -07007582 // Settting the entire storage nicely
7583 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
7584 m_out_mem_ptr,pPlatformEntry);
7585 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
7586 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7587 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7588 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7589 // Set the values when we determine the right HxW param
7590 bufHdr->nAllocLen = 0;
7591 bufHdr->nFilledLen = 0;
7592 bufHdr->pAppPrivate = NULL;
7593 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7594 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7595 pPlatformEntry->entry = pPMEMInfo;
7596 // Initialize the Platform List
7597 pPlatformList->nEntries = 1;
7598 pPlatformList->entryList = pPlatformEntry;
7599 // Keep pBuffer NULL till vdec is opened
7600 bufHdr->pBuffer = NULL;
7601 pPMEMInfo->offset = 0;
7602 pPMEMInfo->pmem_fd = 0;
7603 bufHdr->pPlatformPrivate = pPlatformList;
7604 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007605#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007606 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007607#endif
Arun Menon906de572013-06-18 17:01:40 -07007608 /*Create a mapping between buffers*/
7609 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7610 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7611 &drv_ctx.ptr_outputbuffer[i];
7612 // Move the buffer and buffer header pointers
7613 bufHdr++;
7614 pPMEMInfo++;
7615 pPlatformEntry++;
7616 pPlatformList++;
7617 }
7618 } else {
7619 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
7620 m_out_mem_ptr, pPtr);
7621 if (m_out_mem_ptr) {
7622 free(m_out_mem_ptr);
7623 m_out_mem_ptr = NULL;
7624 }
7625 if (pPtr) {
7626 free(pPtr);
7627 pPtr = NULL;
7628 }
7629 if (drv_ctx.ptr_outputbuffer) {
7630 free(drv_ctx.ptr_outputbuffer);
7631 drv_ctx.ptr_outputbuffer = NULL;
7632 }
7633 if (drv_ctx.ptr_respbuffer) {
7634 free(drv_ctx.ptr_respbuffer);
7635 drv_ctx.ptr_respbuffer = NULL;
7636 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007637#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007638 if (drv_ctx.op_buf_ion_info) {
7639 DEBUG_PRINT_LOW("\n Free o/p ion context");
7640 free(drv_ctx.op_buf_ion_info);
7641 drv_ctx.op_buf_ion_info = NULL;
7642 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007643#endif
Arun Menon906de572013-06-18 17:01:40 -07007644 eRet = OMX_ErrorInsufficientResources;
7645 }
7646 } else {
7647 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007648 }
Arun Menon906de572013-06-18 17:01:40 -07007649 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007650}
7651
7652void omx_vdec::complete_pending_buffer_done_cbs()
7653{
Arun Menon906de572013-06-18 17:01:40 -07007654 unsigned p1;
7655 unsigned p2;
7656 unsigned ident;
7657 omx_cmd_queue tmp_q, pending_bd_q;
7658 pthread_mutex_lock(&m_lock);
7659 // pop all pending GENERATE FDB from ftb queue
7660 while (m_ftb_q.m_size) {
7661 m_ftb_q.pop_entry(&p1,&p2,&ident);
7662 if (ident == OMX_COMPONENT_GENERATE_FBD) {
7663 pending_bd_q.insert_entry(p1,p2,ident);
7664 } else {
7665 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007666 }
Arun Menon906de572013-06-18 17:01:40 -07007667 }
7668 //return all non GENERATE FDB to ftb queue
7669 while (tmp_q.m_size) {
7670 tmp_q.pop_entry(&p1,&p2,&ident);
7671 m_ftb_q.insert_entry(p1,p2,ident);
7672 }
7673 // pop all pending GENERATE EDB from etb queue
7674 while (m_etb_q.m_size) {
7675 m_etb_q.pop_entry(&p1,&p2,&ident);
7676 if (ident == OMX_COMPONENT_GENERATE_EBD) {
7677 pending_bd_q.insert_entry(p1,p2,ident);
7678 } else {
7679 tmp_q.insert_entry(p1,p2,ident);
7680 }
7681 }
7682 //return all non GENERATE FDB to etb queue
7683 while (tmp_q.m_size) {
7684 tmp_q.pop_entry(&p1,&p2,&ident);
7685 m_etb_q.insert_entry(p1,p2,ident);
7686 }
7687 pthread_mutex_unlock(&m_lock);
7688 // process all pending buffer dones
7689 while (pending_bd_q.m_size) {
7690 pending_bd_q.pop_entry(&p1,&p2,&ident);
7691 switch (ident) {
7692 case OMX_COMPONENT_GENERATE_EBD:
7693 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
7694 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
7695 omx_report_error ();
7696 }
7697 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007698
Arun Menon906de572013-06-18 17:01:40 -07007699 case OMX_COMPONENT_GENERATE_FBD:
7700 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
7701 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
7702 omx_report_error ();
7703 }
7704 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007705 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007706 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007707}
7708
7709void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
7710{
Arun Menon906de572013-06-18 17:01:40 -07007711 OMX_U32 new_frame_interval = 0;
7712 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
7713 && llabs(act_timestamp - prev_ts) > 2000) {
7714 new_frame_interval = client_set_fps ? frm_int :
7715 llabs(act_timestamp - prev_ts);
7716 if (new_frame_interval < frm_int || frm_int == 0) {
7717 frm_int = new_frame_interval;
7718 if (frm_int) {
7719 drv_ctx.frame_rate.fps_numerator = 1e6;
7720 drv_ctx.frame_rate.fps_denominator = frm_int;
7721 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
7722 frm_int, drv_ctx.frame_rate.fps_numerator /
7723 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007724
Arun Menon906de572013-06-18 17:01:40 -07007725 /* We need to report the difference between this FBD and the previous FBD
7726 * back to the driver for clock scaling purposes. */
7727 struct v4l2_outputparm oparm;
7728 /*XXX: we're providing timing info as seconds per frame rather than frames
7729 * per second.*/
7730 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
7731 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007732
Arun Menon906de572013-06-18 17:01:40 -07007733 struct v4l2_streamparm sparm;
7734 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7735 sparm.parm.output = oparm;
7736 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
7737 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
7738 performance might be affected");
7739 }
7740
7741 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007742 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007743 }
Arun Menon906de572013-06-18 17:01:40 -07007744 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007745}
7746
7747void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
7748{
Arun Menon906de572013-06-18 17:01:40 -07007749 if (rst_prev_ts && VALID_TS(act_timestamp)) {
7750 prev_ts = act_timestamp;
7751 rst_prev_ts = false;
7752 } else if (VALID_TS(prev_ts)) {
7753 bool codec_cond = (drv_ctx.timestamp_adjust)?
7754 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
7755 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
7756 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
7757 if (frm_int > 0 && codec_cond) {
7758 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
7759 act_timestamp = prev_ts + frm_int;
7760 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
7761 prev_ts = act_timestamp;
7762 } else
7763 set_frame_rate(act_timestamp);
7764 } else if (frm_int > 0) // In this case the frame rate was set along
7765 { // with the port definition, start ts with 0
7766 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
7767 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007768 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007769}
7770
7771void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
7772{
Arun Menon906de572013-06-18 17:01:40 -07007773 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
7774 OMX_U32 num_conceal_MB = 0;
7775 OMX_U32 frame_rate = 0;
7776 int consumed_len = 0;
7777 OMX_U32 num_MB_in_frame;
7778 OMX_U32 recovery_sei_flags = 1;
7779 int enable = 0;
7780 OMX_U32 mbaff = 0;
7781 int buf_index = p_buf_hdr - m_out_mem_ptr;
7782 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
7783 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
7784 p_buf_hdr->nOffset;
7785 if (!drv_ctx.extradata_info.uaddr) {
7786 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007787 }
Arun Menon906de572013-06-18 17:01:40 -07007788 p_extra = (OMX_OTHER_EXTRADATATYPE *)
7789 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
7790 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
7791 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
7792 p_extra = NULL;
7793 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
7794 if (data) {
7795 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
7796 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
7797 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
7798 DEBUG_PRINT_LOW("Invalid extra data size");
7799 break;
7800 }
7801 switch ((unsigned long)data->eType) {
7802 case EXTRADATA_INTERLACE_VIDEO:
7803 struct msm_vidc_interlace_payload *payload;
7804 payload = (struct msm_vidc_interlace_payload *)data->data;
7805 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
7806 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
7807 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
7808 else {
7809 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
7810 enable = 1;
7811 }
7812 if (m_enable_android_native_buffers)
7813 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
7814 PP_PARAM_INTERLACED, (void*)&enable);
7815 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
7816 append_interlace_extradata(p_extra, payload->format);
7817 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
7818 }
7819 break;
7820 case EXTRADATA_FRAME_RATE:
7821 struct msm_vidc_framerate_payload *frame_rate_payload;
7822 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
7823 frame_rate = frame_rate_payload->frame_rate;
7824 break;
7825 case EXTRADATA_TIMESTAMP:
7826 struct msm_vidc_ts_payload *time_stamp_payload;
7827 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
7828 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
7829 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
7830 break;
7831 case EXTRADATA_NUM_CONCEALED_MB:
7832 struct msm_vidc_concealmb_payload *conceal_mb_payload;
7833 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
7834 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
7835 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
7836 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
7837 break;
7838 case EXTRADATA_INDEX:
7839 int *etype;
7840 etype = (int *)(data->data);
7841 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
7842 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
7843 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
7844 if (aspect_ratio_payload) {
7845 ((struct vdec_output_frameinfo *)
7846 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
7847 ((struct vdec_output_frameinfo *)
7848 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
7849 }
7850 }
7851 break;
7852 case EXTRADATA_RECOVERY_POINT_SEI:
7853 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
7854 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
7855 recovery_sei_flags = recovery_sei_payload->flags;
7856 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
7857 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7858 DEBUG_PRINT_HIGH("\n");
7859 DEBUG_PRINT_HIGH("***************************************************\n");
7860 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
7861 DEBUG_PRINT_HIGH("***************************************************\n");
7862 }
7863 break;
7864 case EXTRADATA_PANSCAN_WINDOW:
7865 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
7866 break;
7867 case EXTRADATA_MPEG2_SEQDISP:
7868 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
7869 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
7870 if (seqdisp_payload) {
7871 m_disp_hor_size = seqdisp_payload->disp_width;
7872 m_disp_vert_size = seqdisp_payload->disp_height;
7873 }
7874 break;
7875 default:
7876 goto unrecognized_extradata;
7877 }
7878 consumed_len += data->nSize;
7879 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
7880 }
7881 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
7882 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
7883 append_frame_info_extradata(p_extra,
7884 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
7885 panscan_payload,&((struct vdec_output_frameinfo *)
7886 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
7887 }
7888 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007889unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07007890 if (!secure_mode && client_extradata)
7891 append_terminator_extradata(p_extra);
7892 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007893}
7894
Vinay Kalia9c00cae2012-12-06 16:08:20 -08007895OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07007896 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007897{
Arun Menon906de572013-06-18 17:01:40 -07007898 OMX_ERRORTYPE ret = OMX_ErrorNone;
7899 struct v4l2_control control;
7900 if (m_state != OMX_StateLoaded) {
7901 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
7902 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08007903 }
Arun Menon906de572013-06-18 17:01:40 -07007904 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
7905 client_extradata, requested_extradata, enable, is_internal);
7906
7907 if (!is_internal) {
7908 if (enable)
7909 client_extradata |= requested_extradata;
7910 else
7911 client_extradata = client_extradata & ~requested_extradata;
7912 }
7913
7914 if (enable) {
7915 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
7916 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7917 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
7918 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7919 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
7920 " Quality of interlaced clips might be impacted.\n");
7921 }
7922 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
7923 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7924 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
7925 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7926 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
7927 }
7928 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7929 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
7930 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7931 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
7932 }
7933 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7934 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
7935 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7936 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
7937 }
7938 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7939 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
7940 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7941 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7942 }
7943 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7944 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
7945 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7946 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7947 }
7948 if (output_capability == V4L2_PIX_FMT_MPEG2) {
7949 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7950 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
7951 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7952 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7953 }
7954 }
7955 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
7956 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7957 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
7958 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7959 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
7960 }
7961 }
7962 }
7963 ret = get_buffer_req(&drv_ctx.op_buf);
7964 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007965}
7966
7967OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
7968{
Arun Menon906de572013-06-18 17:01:40 -07007969 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
7970 OMX_U8 *data_ptr = extra->data, data = 0;
7971 while (byte_count < extra->nDataSize) {
7972 data = *data_ptr;
7973 while (data) {
7974 num_MB += (data&0x01);
7975 data >>= 1;
7976 }
7977 data_ptr++;
7978 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007979 }
Arun Menon906de572013-06-18 17:01:40 -07007980 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
7981 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
7982 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007983}
7984
7985void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
7986{
Arun Menon906de572013-06-18 17:01:40 -07007987 if (!m_debug_extradata)
7988 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007989
7990 DEBUG_PRINT_HIGH(
Arun Menon906de572013-06-18 17:01:40 -07007991 "============== Extra Data ==============\n"
7992 " Size: %lu \n"
7993 " Version: %lu \n"
7994 " PortIndex: %lu \n"
7995 " Type: %x \n"
7996 " DataSize: %lu \n",
7997 extra->nSize, extra->nVersion.nVersion,
7998 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007999
Arun Menon906de572013-06-18 17:01:40 -07008000 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8001 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8002 DEBUG_PRINT_HIGH(
8003 "------ Interlace Format ------\n"
8004 " Size: %lu \n"
8005 " Version: %lu \n"
8006 " PortIndex: %lu \n"
8007 " Is Interlace Format: %d \n"
8008 " Interlace Formats: %lu \n"
8009 "=========== End of Interlace ===========\n",
8010 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8011 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8012 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8013 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8014
8015 DEBUG_PRINT_HIGH(
8016 "-------- Frame Format --------\n"
8017 " Picture Type: %d \n"
8018 " Interlace Type: %d \n"
8019 " Pan Scan Total Frame Num: %lu \n"
8020 " Concealed Macro Blocks: %lu \n"
8021 " frame rate: %lu \n"
8022 " Aspect Ratio X: %lu \n"
8023 " Aspect Ratio Y: %lu \n",
8024 fminfo->ePicType,
8025 fminfo->interlaceType,
8026 fminfo->panScan.numWindows,
8027 fminfo->nConcealedMacroblocks,
8028 fminfo->nFrameRate,
8029 fminfo->aspectRatio.aspectRatioX,
8030 fminfo->aspectRatio.aspectRatioY);
8031
8032 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8033 DEBUG_PRINT_HIGH(
8034 "------------------------------\n"
8035 " Pan Scan Frame Num: %lu \n"
8036 " Rectangle x: %ld \n"
8037 " Rectangle y: %ld \n"
8038 " Rectangle dx: %ld \n"
8039 " Rectangle dy: %ld \n",
8040 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8041 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8042 }
8043
8044 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8045 } else if (extra->eType == OMX_ExtraDataNone) {
8046 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8047 } else {
8048 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008049 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008050}
8051
8052void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008053 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008054{
Arun Menon906de572013-06-18 17:01:40 -07008055 OMX_STREAMINTERLACEFORMAT *interlace_format;
8056 OMX_U32 mbaff = 0;
8057 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8058 return;
8059 }
8060 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8061 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8062 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8063 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8064 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8065 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8066 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8067 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8068 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8069 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8070 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8071 interlace_format->bInterlaceFormat = OMX_FALSE;
8072 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8073 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8074 } else {
8075 interlace_format->bInterlaceFormat = OMX_TRUE;
8076 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8077 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8078 }
8079 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008080}
8081
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008082void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008083 struct vdec_aspectratioinfo *aspect_ratio_info,
8084 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008085{
Arun Menon906de572013-06-18 17:01:40 -07008086 m_extradata = frame_info;
8087 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8088 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
8089 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
8090 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008091}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008092
8093void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008094 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008095 struct msm_vidc_panscan_window_payload *panscan_payload,
8096 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008097{
Arun Menon906de572013-06-18 17:01:40 -07008098 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8099 struct msm_vidc_panscan_window *panscan_window;
8100 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008101 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008102 }
Arun Menon906de572013-06-18 17:01:40 -07008103 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8104 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8105 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8106 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8107 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8108 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8109 switch (picture_type) {
8110 case PICTURE_TYPE_I:
8111 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8112 break;
8113 case PICTURE_TYPE_P:
8114 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8115 break;
8116 case PICTURE_TYPE_B:
8117 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8118 break;
8119 default:
8120 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8121 }
8122 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8123 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8124 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8125 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8126 else
8127 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8128 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8129 frame_info->nConcealedMacroblocks = num_conceal_mb;
8130 frame_info->nFrameRate = frame_rate;
8131 frame_info->panScan.numWindows = 0;
8132 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8133 if (m_disp_hor_size && m_disp_vert_size) {
8134 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8135 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8136 }
8137 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008138
Arun Menon906de572013-06-18 17:01:40 -07008139 if (panscan_payload) {
8140 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8141 panscan_window = &panscan_payload->wnd[0];
8142 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8143 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8144 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8145 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8146 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8147 panscan_window++;
8148 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008149 }
Arun Menon906de572013-06-18 17:01:40 -07008150 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8151 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008152}
8153
8154void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8155{
Arun Menon906de572013-06-18 17:01:40 -07008156 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8157 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8158 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8159 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8160 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8161 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8162 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8163 *portDefn = m_port_def;
8164 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8165 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
8166 portDefn->format.video.nFrameWidth,
8167 portDefn->format.video.nStride,
8168 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008169}
8170
8171void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8172{
Arun Menon906de572013-06-18 17:01:40 -07008173 if (!client_extradata) {
8174 return;
8175 }
8176 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8177 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8178 extra->eType = OMX_ExtraDataNone;
8179 extra->nDataSize = 0;
8180 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008181
Arun Menon906de572013-06-18 17:01:40 -07008182 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008183}
8184
8185OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8186{
Arun Menon906de572013-06-18 17:01:40 -07008187 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8188 if (index >= drv_ctx.ip_buf.actualcount) {
8189 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8190 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008191 }
Arun Menon906de572013-06-18 17:01:40 -07008192 if (m_desc_buffer_ptr == NULL) {
8193 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8194 calloc( (sizeof(desc_buffer_hdr)),
8195 drv_ctx.ip_buf.actualcount);
8196 if (m_desc_buffer_ptr == NULL) {
8197 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8198 return OMX_ErrorInsufficientResources;
8199 }
8200 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008201
Arun Menon906de572013-06-18 17:01:40 -07008202 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8203 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
8204 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8205 return OMX_ErrorInsufficientResources;
8206 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008207
Arun Menon906de572013-06-18 17:01:40 -07008208 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008209}
8210
8211void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8212{
Arun Menon906de572013-06-18 17:01:40 -07008213 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8214 if (m_demux_entries < 8192) {
8215 m_demux_offsets[m_demux_entries++] = address_offset;
8216 }
8217 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008218}
8219
8220void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8221{
Arun Menon906de572013-06-18 17:01:40 -07008222 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8223 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8224 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008225
Arun Menon906de572013-06-18 17:01:40 -07008226 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008227
Arun Menon906de572013-06-18 17:01:40 -07008228 while (index < bytes_to_parse) {
8229 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8230 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8231 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8232 (buf[index+2] == 0x01)) ) {
8233 //Found start code, insert address offset
8234 insert_demux_addr_offset(index);
8235 if (buf[index+2] == 0x01) // 3 byte start code
8236 index += 3;
8237 else //4 byte start code
8238 index += 4;
8239 } else
8240 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008241 }
Arun Menon906de572013-06-18 17:01:40 -07008242 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8243 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008244}
8245
8246OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8247{
Arun Menon906de572013-06-18 17:01:40 -07008248 //fix this, handle 3 byte start code, vc1 terminator entry
8249 OMX_U8 *p_demux_data = NULL;
8250 OMX_U32 desc_data = 0;
8251 OMX_U32 start_addr = 0;
8252 OMX_U32 nal_size = 0;
8253 OMX_U32 suffix_byte = 0;
8254 OMX_U32 demux_index = 0;
8255 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008256
Arun Menon906de572013-06-18 17:01:40 -07008257 if (m_desc_buffer_ptr == NULL) {
8258 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8259 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008260 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008261
Arun Menon906de572013-06-18 17:01:40 -07008262 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8263 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8264 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8265 return OMX_ErrorBadParameter;
8266 }
8267
8268 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8269
8270 if ( ((OMX_U8*)p_demux_data == NULL) ||
8271 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8272 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8273 return OMX_ErrorBadParameter;
8274 } else {
8275 for (; demux_index < m_demux_entries; demux_index++) {
8276 desc_data = 0;
8277 start_addr = m_demux_offsets[demux_index];
8278 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8279 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8280 } else {
8281 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8282 }
8283 if (demux_index < (m_demux_entries - 1)) {
8284 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8285 } else {
8286 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8287 }
8288 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8289 (void *)start_addr,
8290 suffix_byte,
8291 nal_size,
8292 demux_index);
8293 desc_data = (start_addr >> 3) << 1;
8294 desc_data |= (start_addr & 7) << 21;
8295 desc_data |= suffix_byte << 24;
8296
8297 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8298 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8299 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8300 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8301
8302 p_demux_data += 16;
8303 }
8304 if (codec_type_parse == CODEC_TYPE_VC1) {
8305 DEBUG_PRINT_LOW("VC1 terminator entry");
8306 desc_data = 0;
8307 desc_data = 0x82 << 24;
8308 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8309 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8310 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8311 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8312 p_demux_data += 16;
8313 m_demux_entries++;
8314 }
8315 //Add zero word to indicate end of descriptors
8316 memset(p_demux_data, 0, sizeof(OMX_U32));
8317
8318 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8319 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8320 }
8321 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8322 m_demux_entries = 0;
8323 DEBUG_PRINT_LOW("Demux table complete!");
8324 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008325}
8326
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008327OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008328{
Arun Menon906de572013-06-18 17:01:40 -07008329 OMX_ERRORTYPE err = OMX_ErrorNone;
8330 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8331 if (iDivXDrmDecrypt) {
8332 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8333 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008334 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008335 delete iDivXDrmDecrypt;
8336 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008337 }
8338 } else {
8339 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
8340 err = OMX_ErrorUndefined;
8341 }
8342 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008343}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008344
Vinay Kaliada4f4422013-01-09 10:45:03 -08008345omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8346{
Arun Menon906de572013-06-18 17:01:40 -07008347 enabled = false;
8348 omx = NULL;
8349 init_members();
8350 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008351}
8352
8353void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8354{
Arun Menon906de572013-06-18 17:01:40 -07008355 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008356}
8357
Arun Menon906de572013-06-18 17:01:40 -07008358void omx_vdec::allocate_color_convert_buf::init_members()
8359{
8360 allocated_count = 0;
8361 buffer_size_req = 0;
8362 buffer_alignment_req = 0;
8363 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8364 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8365 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8366 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008367#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008368 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008369#endif
Arun Menon906de572013-06-18 17:01:40 -07008370 for (int i = 0; i < MAX_COUNT; i++)
8371 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008372}
8373
Arun Menon906de572013-06-18 17:01:40 -07008374omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8375{
8376 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008377}
8378
8379bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8380{
Arun Menon906de572013-06-18 17:01:40 -07008381 bool status = true;
8382 unsigned int src_size = 0, destination_size = 0;
8383 OMX_COLOR_FORMATTYPE drv_color_format;
8384 if (!omx) {
8385 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8386 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008387 }
Arun Menon906de572013-06-18 17:01:40 -07008388 if (!enabled) {
8389 DEBUG_PRINT_HIGH("\n No color conversion required");
8390 return status;
8391 }
8392 pthread_mutex_lock(&omx->c_lock);
8393 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8394 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8395 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
8396 status = false;
8397 goto fail_update_buf_req;
8398 }
8399 c2d.close();
8400 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8401 omx->drv_ctx.video_resolution.frame_width,
8402 NV12_128m,YCbCr420P);
8403 if (status) {
8404 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8405 if (status)
8406 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8407 }
8408 if (status) {
8409 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8410 !destination_size) {
8411 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
8412 "driver size %d destination size %d",
8413 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8414 status = false;
8415 c2d.close();
8416 buffer_size_req = 0;
8417 } else {
8418 buffer_size_req = destination_size;
8419 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8420 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8421 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8422 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8423 }
8424 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008425fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008426 pthread_mutex_unlock(&omx->c_lock);
8427 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008428}
8429
8430bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008431 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008432{
Arun Menon906de572013-06-18 17:01:40 -07008433 bool status = true;
8434 OMX_COLOR_FORMATTYPE drv_color_format;
8435 if (!omx) {
8436 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8437 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008438 }
Arun Menon906de572013-06-18 17:01:40 -07008439 pthread_mutex_lock(&omx->c_lock);
8440 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8441 drv_color_format = (OMX_COLOR_FORMATTYPE)
8442 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8443 else {
8444 DEBUG_PRINT_ERROR("\n Incorrect color format");
8445 status = false;
8446 }
8447 if (status && (drv_color_format != dest_color_format)) {
8448 DEBUG_PRINT_LOW("Enabling C2D\n");
8449 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
8450 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
8451 status = false;
8452 } else {
8453 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8454 if (enabled)
8455 c2d.destroy();
8456 enabled = false;
8457 if (!c2d.init()) {
8458 DEBUG_PRINT_ERROR("\n open failed for c2d");
8459 status = false;
8460 } else
8461 enabled = true;
8462 }
8463 } else {
8464 if (enabled)
8465 c2d.destroy();
8466 enabled = false;
8467 }
8468 pthread_mutex_unlock(&omx->c_lock);
8469 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008470}
8471
8472OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8473{
Arun Menon906de572013-06-18 17:01:40 -07008474 if (!omx) {
8475 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8476 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008477 }
Arun Menon906de572013-06-18 17:01:40 -07008478 if (!enabled)
8479 return omx->m_out_mem_ptr;
8480 return m_out_mem_ptr_client;
8481}
8482
8483 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
8484(OMX_BUFFERHEADERTYPE *bufadd)
8485{
8486 if (!omx) {
8487 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8488 return NULL;
8489 }
8490 if (!enabled)
8491 return bufadd;
8492
8493 unsigned index = 0;
8494 index = bufadd - omx->m_out_mem_ptr;
8495 if (index < omx->drv_ctx.op_buf.actualcount) {
8496 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
8497 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
8498 bool status;
8499 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
8500 pthread_mutex_lock(&omx->c_lock);
8501 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
8502 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
8503 pmem_baseaddress[index], pmem_baseaddress[index]);
8504 pthread_mutex_unlock(&omx->c_lock);
8505 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
8506 if (!status) {
8507 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
8508 m_out_mem_ptr_client[index].nFilledLen = 0;
8509 return &m_out_mem_ptr_client[index];
8510 }
8511 } else
8512 m_out_mem_ptr_client[index].nFilledLen = 0;
8513 return &m_out_mem_ptr_client[index];
8514 }
8515 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
8516 return NULL;
8517}
8518
8519 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
8520(OMX_BUFFERHEADERTYPE *bufadd)
8521{
8522 if (!omx) {
8523 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8524 return NULL;
8525 }
8526 if (!enabled)
8527 return bufadd;
8528 unsigned index = 0;
8529 index = bufadd - m_out_mem_ptr_client;
8530 if (index < omx->drv_ctx.op_buf.actualcount) {
8531 return &omx->m_out_mem_ptr[index];
8532 }
8533 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
8534 return NULL;
8535}
8536 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
8537(unsigned int &buffer_size)
8538{
8539 bool status = true;
8540 pthread_mutex_lock(&omx->c_lock);
8541 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008542 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07008543 else {
8544 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
8545 DEBUG_PRINT_ERROR("\n Get buffer size failed");
8546 status = false;
8547 goto fail_get_buffer_size;
8548 }
8549 }
8550 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
8551 buffer_size = omx->drv_ctx.op_buf.buffer_size;
8552 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8553 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008554fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07008555 pthread_mutex_unlock(&omx->c_lock);
8556 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008557}
8558OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07008559 OMX_BUFFERHEADERTYPE *bufhdr)
8560{
8561 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008562
Arun Menon906de572013-06-18 17:01:40 -07008563 if (!enabled)
8564 return omx->free_output_buffer(bufhdr);
8565 if (enabled && omx->is_component_secure())
8566 return OMX_ErrorNone;
8567 if (!allocated_count || !bufhdr) {
8568 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
8569 return OMX_ErrorBadParameter;
8570 }
8571 index = bufhdr - m_out_mem_ptr_client;
8572 if (index >= omx->drv_ctx.op_buf.actualcount) {
8573 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
8574 return OMX_ErrorBadParameter;
8575 }
8576 if (pmem_fd[index] > 0) {
8577 munmap(pmem_baseaddress[index], buffer_size_req);
8578 close(pmem_fd[index]);
8579 }
8580 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008581#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008582 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008583#endif
Arun Menon906de572013-06-18 17:01:40 -07008584 m_heap_ptr[index].video_heap_ptr = NULL;
8585 if (allocated_count > 0)
8586 allocated_count--;
8587 else
8588 allocated_count = 0;
8589 if (!allocated_count) {
8590 pthread_mutex_lock(&omx->c_lock);
8591 c2d.close();
8592 init_members();
8593 pthread_mutex_unlock(&omx->c_lock);
8594 }
8595 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008596}
8597
8598OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07008599 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008600{
Arun Menon906de572013-06-18 17:01:40 -07008601 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8602 if (!enabled) {
8603 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
8604 return eRet;
8605 }
8606 if (enabled && omx->is_component_secure()) {
8607 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
8608 omx->is_component_secure());
8609 return OMX_ErrorUnsupportedSetting;
8610 }
8611 if (!bufferHdr || bytes > buffer_size_req) {
8612 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
8613 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
8614 buffer_size_req,bytes);
8615 return OMX_ErrorBadParameter;
8616 }
8617 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
8618 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
8619 return OMX_ErrorInsufficientResources;
8620 }
8621 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
8622 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
8623 port,appData,omx->drv_ctx.op_buf.buffer_size);
8624 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
8625 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
8626 return eRet;
8627 }
8628 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
8629 omx->drv_ctx.op_buf.actualcount) {
8630 DEBUG_PRINT_ERROR("\n Invalid header index %d",
8631 (temp_bufferHdr - omx->m_out_mem_ptr));
8632 return OMX_ErrorUndefined;
8633 }
8634 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008635#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008636 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
8637 buffer_size_req,buffer_alignment_req,
8638 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
8639 0);
8640 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
8641 if (op_buf_ion_info[i].ion_device_fd < 0) {
8642 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
8643 return OMX_ErrorInsufficientResources;
8644 }
8645 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
8646 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008647
Arun Menon906de572013-06-18 17:01:40 -07008648 if (pmem_baseaddress[i] == MAP_FAILED) {
8649 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
8650 close(pmem_fd[i]);
8651 omx->free_ion_memory(&op_buf_ion_info[i]);
8652 return OMX_ErrorInsufficientResources;
8653 }
8654 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
8655 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
8656 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008657#endif
Arun Menon906de572013-06-18 17:01:40 -07008658 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
8659 m_pmem_info_client[i].offset = 0;
8660 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
8661 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8662 m_platform_list_client[i].nEntries = 1;
8663 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
8664 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
8665 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
8666 m_out_mem_ptr_client[i].nFilledLen = 0;
8667 m_out_mem_ptr_client[i].nFlags = 0;
8668 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8669 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
8670 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
8671 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
8672 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
8673 m_out_mem_ptr_client[i].pAppPrivate = appData;
8674 *bufferHdr = &m_out_mem_ptr_client[i];
8675 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
8676 allocated_count++;
8677 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008678}
8679
8680bool omx_vdec::is_component_secure()
8681{
Arun Menon906de572013-06-18 17:01:40 -07008682 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008683}
8684
8685bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
8686{
Arun Menon906de572013-06-18 17:01:40 -07008687 bool status = true;
8688 if (!enabled) {
8689 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8690 dest_color_format = (OMX_COLOR_FORMATTYPE)
8691 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8692 else
8693 status = false;
8694 } else {
8695 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8696 status = false;
8697 } else
8698 dest_color_format = OMX_COLOR_FormatYUV420Planar;
8699 }
8700 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008701}