blob: fcc3cb530410b6e457d7e01f8b69105fc2181eec [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) {
4315 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4316 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4317 drv_ctx.ip_buf.actualcount);
4318 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4319 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4320 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004321
Arun Menon906de572013-06-18 17:01:40 -07004322 if (m_inp_heap_ptr == NULL) {
4323 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4324 return OMX_ErrorInsufficientResources;
4325 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004326 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004327
Arun Menon906de572013-06-18 17:01:40 -07004328 /*Find a Free index*/
4329 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4330 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
4331 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4332 break;
4333 }
4334 }
4335
4336 if (i < drv_ctx.ip_buf.actualcount) {
4337 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4338
4339 if (buf_addr == NULL) {
4340 return OMX_ErrorInsufficientResources;
4341 }
4342
4343 *bufferHdr = (m_inp_heap_ptr + i);
4344 input = *bufferHdr;
4345 BITMASK_SET(&m_heap_inp_bm_count,i);
4346
4347 input->pBuffer = (OMX_U8 *)buf_addr;
4348 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4349 input->nVersion.nVersion = OMX_SPEC_VERSION;
4350 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4351 input->pAppPrivate = appData;
4352 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4353 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4354 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4355 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
4356 /*Add the Buffers to freeq*/
4357 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4358 (unsigned)NULL, (unsigned)NULL)) {
4359 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4360 return OMX_ErrorInsufficientResources;
4361 }
4362 } else {
4363 return OMX_ErrorBadParameter;
4364 }
4365
4366 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004367
4368}
4369
4370
4371/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004372 FUNCTION
4373 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004374
Arun Menon906de572013-06-18 17:01:40 -07004375 DESCRIPTION
4376 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004377
Arun Menon906de572013-06-18 17:01:40 -07004378 PARAMETERS
4379 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004380
Arun Menon906de572013-06-18 17:01:40 -07004381 RETURN VALUE
4382 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004383
Arun Menon906de572013-06-18 17:01:40 -07004384 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004385OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004386 OMX_IN OMX_HANDLETYPE hComp,
4387 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4388 OMX_IN OMX_U32 port,
4389 OMX_IN OMX_PTR appData,
4390 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004391{
4392
Arun Menon906de572013-06-18 17:01:40 -07004393 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4394 struct vdec_setbuffer_cmd setbuffers;
4395 OMX_BUFFERHEADERTYPE *input = NULL;
4396 unsigned i = 0;
4397 unsigned char *buf_addr = NULL;
4398 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004399
Arun Menon906de572013-06-18 17:01:40 -07004400 if (bytes != drv_ctx.ip_buf.buffer_size) {
4401 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
4402 bytes, drv_ctx.ip_buf.buffer_size);
4403 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004404 }
4405
Arun Menon906de572013-06-18 17:01:40 -07004406 if (!m_inp_mem_ptr) {
4407 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4408 drv_ctx.ip_buf.actualcount,
4409 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004410
Arun Menon906de572013-06-18 17:01:40 -07004411 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4412 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4413
4414 if (m_inp_mem_ptr == NULL) {
4415 return OMX_ErrorInsufficientResources;
4416 }
4417
4418 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4419 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4420
4421 if (drv_ctx.ptr_inputbuffer == NULL) {
4422 return OMX_ErrorInsufficientResources;
4423 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004424#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004425 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4426 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004427
Arun Menon906de572013-06-18 17:01:40 -07004428 if (drv_ctx.ip_buf_ion_info == NULL) {
4429 return OMX_ErrorInsufficientResources;
4430 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004431#endif
4432
Arun Menon906de572013-06-18 17:01:40 -07004433 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4434 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004435#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004436 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004437#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004438 }
4439 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004440
Arun Menon906de572013-06-18 17:01:40 -07004441 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4442 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4443 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4444 break;
4445 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004446 }
Arun Menon906de572013-06-18 17:01:40 -07004447
4448 if (i < drv_ctx.ip_buf.actualcount) {
4449 struct v4l2_buffer buf;
4450 struct v4l2_plane plane;
4451 int rc;
4452 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4453#ifdef USE_ION
4454 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4455 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4456 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4457 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4458 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4459 return OMX_ErrorInsufficientResources;
4460 }
4461 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4462#else
4463 pmem_fd = open (MEM_DEVICE,O_RDWR);
4464
4465 if (pmem_fd < 0) {
4466 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4467 return OMX_ErrorInsufficientResources;
4468 }
4469
4470 if (pmem_fd == 0) {
4471 pmem_fd = open (MEM_DEVICE,O_RDWR);
4472
4473 if (pmem_fd < 0) {
4474 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4475 return OMX_ErrorInsufficientResources;
4476 }
4477 }
4478
4479 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4480 drv_ctx.ip_buf.alignment)) {
4481 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4482 close(pmem_fd);
4483 return OMX_ErrorInsufficientResources;
4484 }
4485#endif
4486 if (!secure_mode) {
4487 buf_addr = (unsigned char *)mmap(NULL,
4488 drv_ctx.ip_buf.buffer_size,
4489 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4490
4491 if (buf_addr == MAP_FAILED) {
4492 close(pmem_fd);
4493#ifdef USE_ION
4494 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4495#endif
4496 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4497 return OMX_ErrorInsufficientResources;
4498 }
4499 }
4500 *bufferHdr = (m_inp_mem_ptr + i);
4501 if (secure_mode)
4502 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4503 else
4504 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4505 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4506 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4507 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4508 drv_ctx.ptr_inputbuffer [i].offset = 0;
4509
4510
4511 buf.index = i;
4512 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4513 buf.memory = V4L2_MEMORY_USERPTR;
4514 plane.bytesused = 0;
4515 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4516 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4517 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4518 plane.reserved[1] = 0;
4519 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4520 buf.m.planes = &plane;
4521 buf.length = 1;
4522
4523 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4524 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4525
4526 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4527
4528 if (rc) {
4529 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4530 /*TODO: How to handle this case */
4531 return OMX_ErrorInsufficientResources;
4532 }
4533
4534 input = *bufferHdr;
4535 BITMASK_SET(&m_inp_bm_count,i);
4536 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4537 if (secure_mode)
4538 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4539 else
4540 input->pBuffer = (OMX_U8 *)buf_addr;
4541 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4542 input->nVersion.nVersion = OMX_SPEC_VERSION;
4543 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4544 input->pAppPrivate = appData;
4545 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4546 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4547
4548 if (drv_ctx.disable_dmx) {
4549 eRet = allocate_desc_buffer(i);
4550 }
4551 } else {
4552 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4553 eRet = OMX_ErrorInsufficientResources;
4554 }
4555 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004556}
4557
4558
4559/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004560 FUNCTION
4561 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004562
Arun Menon906de572013-06-18 17:01:40 -07004563 DESCRIPTION
4564 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004565
Arun Menon906de572013-06-18 17:01:40 -07004566 PARAMETERS
4567 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004568
Arun Menon906de572013-06-18 17:01:40 -07004569 RETURN VALUE
4570 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004571
Arun Menon906de572013-06-18 17:01:40 -07004572 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004573OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004574 OMX_IN OMX_HANDLETYPE hComp,
4575 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4576 OMX_IN OMX_U32 port,
4577 OMX_IN OMX_PTR appData,
4578 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004579{
Arun Menon906de572013-06-18 17:01:40 -07004580 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4581 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4582 unsigned i= 0; // Temporary counter
4583 struct vdec_setbuffer_cmd setbuffers;
4584 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004585#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004586 int ion_device_fd =-1;
4587 struct ion_allocation_data ion_alloc_data;
4588 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004589#endif
Arun Menon906de572013-06-18 17:01:40 -07004590 if (!m_out_mem_ptr) {
4591 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4592 drv_ctx.op_buf.actualcount,
4593 drv_ctx.op_buf.buffer_size);
4594 int nBufHdrSize = 0;
4595 int nPlatformEntrySize = 0;
4596 int nPlatformListSize = 0;
4597 int nPMEMInfoSize = 0;
4598 int pmem_fd = -1;
4599 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004600
Arun Menon906de572013-06-18 17:01:40 -07004601 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4602 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4603 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004604
Arun Menon906de572013-06-18 17:01:40 -07004605 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4606 drv_ctx.op_buf.actualcount);
4607 nBufHdrSize = drv_ctx.op_buf.actualcount *
4608 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004609
Arun Menon906de572013-06-18 17:01:40 -07004610 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4611 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4612 nPlatformListSize = drv_ctx.op_buf.actualcount *
4613 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4614 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4615 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004616
Arun Menon906de572013-06-18 17:01:40 -07004617 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4618 sizeof(OMX_BUFFERHEADERTYPE),
4619 nPMEMInfoSize,
4620 nPlatformListSize);
4621 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4622 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004623#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004624 ion_device_fd = alloc_map_ion_memory(
4625 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4626 drv_ctx.op_buf.alignment,
4627 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4628 if (ion_device_fd < 0) {
4629 return OMX_ErrorInsufficientResources;
4630 }
4631 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004632#else
Arun Menon906de572013-06-18 17:01:40 -07004633 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004634
Arun Menon906de572013-06-18 17:01:40 -07004635 if (pmem_fd < 0) {
4636 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4637 drv_ctx.op_buf.buffer_size);
4638 return OMX_ErrorInsufficientResources;
4639 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004640
Arun Menon906de572013-06-18 17:01:40 -07004641 if (pmem_fd == 0) {
4642 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004643
Arun Menon906de572013-06-18 17:01:40 -07004644 if (pmem_fd < 0) {
4645 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4646 drv_ctx.op_buf.buffer_size);
4647 return OMX_ErrorInsufficientResources;
4648 }
4649 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004650
Arun Menon906de572013-06-18 17:01:40 -07004651 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4652 drv_ctx.op_buf.actualcount,
4653 drv_ctx.op_buf.alignment)) {
4654 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4655 close(pmem_fd);
4656 return OMX_ErrorInsufficientResources;
4657 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004658#endif
Arun Menon906de572013-06-18 17:01:40 -07004659 if (!secure_mode) {
4660 pmem_baseaddress = (unsigned char *)mmap(NULL,
4661 (drv_ctx.op_buf.buffer_size *
4662 drv_ctx.op_buf.actualcount),
4663 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4664 if (pmem_baseaddress == MAP_FAILED) {
4665 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4666 drv_ctx.op_buf.buffer_size);
4667 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004668#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004669 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004670#endif
Arun Menon906de572013-06-18 17:01:40 -07004671 return OMX_ErrorInsufficientResources;
4672 }
4673 }
4674 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4675 // Alloc mem for platform specific info
4676 char *pPtr=NULL;
4677 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4678 nPMEMInfoSize,1);
4679 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4680 calloc (sizeof(struct vdec_bufferpayload),
4681 drv_ctx.op_buf.actualcount);
4682 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4683 calloc (sizeof (struct vdec_output_frameinfo),
4684 drv_ctx.op_buf.actualcount);
4685#ifdef USE_ION
4686 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4687 calloc (sizeof(struct vdec_ion),
4688 drv_ctx.op_buf.actualcount);
4689#endif
4690
4691 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4692 && drv_ctx.ptr_respbuffer) {
4693 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4694 (drv_ctx.op_buf.buffer_size *
4695 drv_ctx.op_buf.actualcount);
4696 bufHdr = m_out_mem_ptr;
4697 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4698 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4699 (((char *) m_platform_list) + nPlatformListSize);
4700 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4701 (((char *) m_platform_entry) + nPlatformEntrySize);
4702 pPlatformList = m_platform_list;
4703 pPlatformEntry = m_platform_entry;
4704 pPMEMInfo = m_pmem_info;
4705
4706 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
4707
4708 // Settting the entire storage nicely
4709 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
4710 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
4711 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4712 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4713 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4714 // Set the values when we determine the right HxW param
4715 bufHdr->nAllocLen = bytes;
4716 bufHdr->nFilledLen = 0;
4717 bufHdr->pAppPrivate = appData;
4718 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4719 // Platform specific PMEM Information
4720 // Initialize the Platform Entry
4721 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
4722 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4723 pPlatformEntry->entry = pPMEMInfo;
4724 // Initialize the Platform List
4725 pPlatformList->nEntries = 1;
4726 pPlatformList->entryList = pPlatformEntry;
4727 // Keep pBuffer NULL till vdec is opened
4728 bufHdr->pBuffer = NULL;
4729 bufHdr->nOffset = 0;
4730
4731 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4732 pPMEMInfo->pmem_fd = 0;
4733 bufHdr->pPlatformPrivate = pPlatformList;
4734
4735 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
4736 m_pmem_info[i].pmem_fd = pmem_fd;
4737#ifdef USE_ION
4738 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
4739 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
4740 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
4741#endif
4742
4743 /*Create a mapping between buffers*/
4744 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
4745 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
4746 &drv_ctx.ptr_outputbuffer[i];
4747 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
4748 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4749 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
4750
4751 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
4752 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
4753 drv_ctx.ptr_outputbuffer[i].bufferaddr);
4754 // Move the buffer and buffer header pointers
4755 bufHdr++;
4756 pPMEMInfo++;
4757 pPlatformEntry++;
4758 pPlatformList++;
4759 }
4760 } else {
4761 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
4762 m_out_mem_ptr, pPtr);
4763 if (m_out_mem_ptr) {
4764 free(m_out_mem_ptr);
4765 m_out_mem_ptr = NULL;
4766 }
4767 if (pPtr) {
4768 free(pPtr);
4769 pPtr = NULL;
4770 }
4771 if (drv_ctx.ptr_outputbuffer) {
4772 free(drv_ctx.ptr_outputbuffer);
4773 drv_ctx.ptr_outputbuffer = NULL;
4774 }
4775 if (drv_ctx.ptr_respbuffer) {
4776 free(drv_ctx.ptr_respbuffer);
4777 drv_ctx.ptr_respbuffer = NULL;
4778 }
4779#ifdef USE_ION
4780 if (drv_ctx.op_buf_ion_info) {
4781 DEBUG_PRINT_LOW("\n Free o/p ion context");
4782 free(drv_ctx.op_buf_ion_info);
4783 drv_ctx.op_buf_ion_info = NULL;
4784 }
4785#endif
4786 eRet = OMX_ErrorInsufficientResources;
4787 }
4788 if (eRet == OMX_ErrorNone)
4789 eRet = allocate_extradata();
4790 }
4791
4792 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4793 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4794 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
4795 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004796 }
4797 }
Arun Menon906de572013-06-18 17:01:40 -07004798
4799 if (eRet == OMX_ErrorNone) {
4800 if (i < drv_ctx.op_buf.actualcount) {
4801 struct v4l2_buffer buf;
4802 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4803 int rc;
4804 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4805
4806 drv_ctx.ptr_outputbuffer[i].buffer_len =
4807 drv_ctx.op_buf.buffer_size;
4808
4809 *bufferHdr = (m_out_mem_ptr + i );
4810 if (secure_mode) {
4811 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4812 }
4813 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
4814
4815 buf.index = i;
4816 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4817 buf.memory = V4L2_MEMORY_USERPTR;
4818 plane[0].length = drv_ctx.op_buf.buffer_size;
4819 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4820 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004821#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004822 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004823#endif
Arun Menon906de572013-06-18 17:01:40 -07004824 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4825 plane[0].data_offset = 0;
4826 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4827 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4828 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4829 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 -07004830#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004831 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004832#endif
Arun Menon906de572013-06-18 17:01:40 -07004833 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4834 plane[extra_idx].data_offset = 0;
4835 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4836 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
4837 return OMX_ErrorBadParameter;
4838 }
4839 buf.m.planes = plane;
4840 buf.length = drv_ctx.num_planes;
4841 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
4842 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4843 if (rc) {
4844 /*TODO: How to handle this case */
4845 return OMX_ErrorInsufficientResources;
4846 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004847
Arun Menon906de572013-06-18 17:01:40 -07004848 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
4849 enum v4l2_buf_type buf_type;
4850 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4851 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
4852 if (rc) {
4853 return OMX_ErrorInsufficientResources;
4854 } else {
4855 streaming[CAPTURE_PORT] = true;
4856 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4857 }
4858 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004859
Arun Menon906de572013-06-18 17:01:40 -07004860 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
4861 (*bufferHdr)->pAppPrivate = appData;
4862 BITMASK_SET(&m_out_bm_count,i);
4863 } else {
4864 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
4865 eRet = OMX_ErrorInsufficientResources;
4866 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004867 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004868
Arun Menon906de572013-06-18 17:01:40 -07004869 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004870}
4871
4872
4873// AllocateBuffer -- API Call
4874/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004875 FUNCTION
4876 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004877
Arun Menon906de572013-06-18 17:01:40 -07004878 DESCRIPTION
4879 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07004880
Arun Menon906de572013-06-18 17:01:40 -07004881 PARAMETERS
4882 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004883
Arun Menon906de572013-06-18 17:01:40 -07004884 RETURN VALUE
4885 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004886
Arun Menon906de572013-06-18 17:01:40 -07004887 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004888OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004889 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4890 OMX_IN OMX_U32 port,
4891 OMX_IN OMX_PTR appData,
4892 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004893{
4894 unsigned i = 0;
4895 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
4896
4897 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07004898 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004899 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
4900 return OMX_ErrorInvalidState;
4901 }
4902
Arun Menon906de572013-06-18 17:01:40 -07004903 if (port == OMX_CORE_INPUT_PORT_INDEX) {
4904 if (arbitrary_bytes) {
4905 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
4906 } else {
4907 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
4908 }
4909 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08004910 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
4911 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07004912 } else {
4913 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4914 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004915 }
4916 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07004917 if (eRet == OMX_ErrorNone) {
4918 if (allocate_done()) {
4919 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004920 // Send the callback now
4921 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4922 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07004923 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004924 }
4925 }
Arun Menon906de572013-06-18 17:01:40 -07004926 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
4927 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4928 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4929 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004930 OMX_CORE_INPUT_PORT_INDEX,
4931 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07004932 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004933 }
Arun Menon906de572013-06-18 17:01:40 -07004934 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
4935 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4936 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004937 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07004938 OMX_CORE_OUTPUT_PORT_INDEX,
4939 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004940 }
4941 }
4942 }
4943 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
4944 return eRet;
4945}
4946
4947// Free Buffer - API call
4948/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004949 FUNCTION
4950 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004951
Arun Menon906de572013-06-18 17:01:40 -07004952 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07004953
Arun Menon906de572013-06-18 17:01:40 -07004954 PARAMETERS
4955 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004956
Arun Menon906de572013-06-18 17:01:40 -07004957 RETURN VALUE
4958 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004959
Arun Menon906de572013-06-18 17:01:40 -07004960 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004961OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004962 OMX_IN OMX_U32 port,
4963 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004964{
4965 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4966 unsigned int nPortIndex;
4967 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
4968
Arun Menon906de572013-06-18 17:01:40 -07004969 if (m_state == OMX_StateIdle &&
4970 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004971 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
Arun Menon906de572013-06-18 17:01:40 -07004972 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
4973 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07004974 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Arun Menon906de572013-06-18 17:01:40 -07004975 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
4976 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
4977 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
4978 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Arun Menon9f098152013-05-08 13:53:54 -07004979 DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port);
Arun Menon906de572013-06-18 17:01:40 -07004980 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004981 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
4982 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07004983 OMX_ErrorPortUnpopulated,
4984 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004985
4986 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07004987 } else if (m_state != OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004988 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
4989 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07004990 OMX_ErrorPortUnpopulated,
4991 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004992 }
4993
Arun Menon906de572013-06-18 17:01:40 -07004994 if (port == OMX_CORE_INPUT_PORT_INDEX) {
4995 /*Check if arbitrary bytes*/
4996 if (!arbitrary_bytes && !input_use_buffer)
4997 nPortIndex = buffer - m_inp_mem_ptr;
4998 else
4999 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005000
5001 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005002 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5003 // Clear the bit associated with it.
5004 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5005 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5006 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005007
Arun Menon906de572013-06-18 17:01:40 -07005008 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5009 if (m_phdr_pmem_ptr)
5010 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5011 } else {
5012 if (arbitrary_bytes) {
5013 if (m_phdr_pmem_ptr)
5014 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5015 else
5016 free_input_buffer(nPortIndex,NULL);
5017 } else
5018 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005019 }
Arun Menon906de572013-06-18 17:01:40 -07005020 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305021 if(release_input_done())
5022 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005023 /*Free the Buffer Header*/
5024 if (release_input_done()) {
5025 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5026 free_input_buffer_header();
5027 }
5028 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005029 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5030 eRet = OMX_ErrorBadPortIndex;
5031 }
5032
Arun Menon906de572013-06-18 17:01:40 -07005033 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5034 && release_input_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005035 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5036 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5037 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005038 OMX_CORE_INPUT_PORT_INDEX,
5039 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005040 }
Arun Menon906de572013-06-18 17:01:40 -07005041 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005042 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005043 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005044 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005045 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5046 // Clear the bit associated with it.
5047 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5048 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005049 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005050
Surajit Podder12aefac2013-08-06 18:43:32 +05305051 if(release_output_done()) {
5052 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5053 }
Arun Menon906de572013-06-18 17:01:40 -07005054 if (release_output_done()) {
5055 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005056 }
Arun Menon906de572013-06-18 17:01:40 -07005057 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005058 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5059 eRet = OMX_ErrorBadPortIndex;
5060 }
Arun Menon906de572013-06-18 17:01:40 -07005061 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5062 && release_output_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005063 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5064
Arun Menon906de572013-06-18 17:01:40 -07005065 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5066 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005067#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005068 if (m_enable_android_native_buffers) {
5069 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5070 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5071 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005072#endif
5073
Arun Menon906de572013-06-18 17:01:40 -07005074 post_event(OMX_CommandPortDisable,
5075 OMX_CORE_OUTPUT_PORT_INDEX,
5076 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005077 }
Arun Menon906de572013-06-18 17:01:40 -07005078 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005079 eRet = OMX_ErrorBadPortIndex;
5080 }
Arun Menon906de572013-06-18 17:01:40 -07005081 if ((eRet == OMX_ErrorNone) &&
5082 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5083 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005084 // Send the callback now
5085 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5086 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005087 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005088 }
5089 }
5090 return eRet;
5091}
5092
5093
5094/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005095 FUNCTION
5096 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005097
Arun Menon906de572013-06-18 17:01:40 -07005098 DESCRIPTION
5099 This routine is used to push the encoded video frames to
5100 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005101
Arun Menon906de572013-06-18 17:01:40 -07005102 PARAMETERS
5103 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005104
Arun Menon906de572013-06-18 17:01:40 -07005105 RETURN VALUE
5106 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005107
Arun Menon906de572013-06-18 17:01:40 -07005108 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005109OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005110 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005111{
Arun Menon906de572013-06-18 17:01:40 -07005112 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5113 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005114
Arun Menon906de572013-06-18 17:01:40 -07005115 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5116 codec_config_flag = true;
5117 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5118 } else {
5119 codec_config_flag = false;
5120 }
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07005121
Arun Menon906de572013-06-18 17:01:40 -07005122 if (m_state == OMX_StateInvalid) {
5123 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5124 return OMX_ErrorInvalidState;
5125 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005126
Arun Menon906de572013-06-18 17:01:40 -07005127 if (buffer == NULL) {
5128 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5129 return OMX_ErrorBadParameter;
5130 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005131
Arun Menon906de572013-06-18 17:01:40 -07005132 if (!m_inp_bEnabled) {
5133 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5134 return OMX_ErrorIncorrectStateOperation;
5135 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005136
Arun Menon906de572013-06-18 17:01:40 -07005137 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
5138 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
5139 return OMX_ErrorBadPortIndex;
5140 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005141
5142#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005143 if (iDivXDrmDecrypt) {
5144 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5145 if (drmErr != OMX_ErrorNone) {
5146 // this error can be ignored
5147 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5148 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005149 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005150#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005151 if (perf_flag) {
5152 if (!latency) {
5153 dec_time.stop();
5154 latency = dec_time.processing_time_us();
5155 dec_time.start();
5156 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005157 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005158
Arun Menon906de572013-06-18 17:01:40 -07005159 if (arbitrary_bytes) {
5160 nBufferIndex = buffer - m_inp_heap_ptr;
5161 } else {
5162 if (input_use_buffer == true) {
5163 nBufferIndex = buffer - m_inp_heap_ptr;
5164 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5165 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5166 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5167 buffer = &m_inp_mem_ptr[nBufferIndex];
5168 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5169 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5170 } else {
5171 nBufferIndex = buffer - m_inp_mem_ptr;
5172 }
5173 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005174
Arun Menon906de572013-06-18 17:01:40 -07005175 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
5176 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5177 return OMX_ErrorBadParameter;
5178 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005179
Arun Menon906de572013-06-18 17:01:40 -07005180 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5181 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5182 if (arbitrary_bytes) {
5183 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005184 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005185 } else {
5186 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5187 set_frame_rate(buffer->nTimeStamp);
5188 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5189 }
5190 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005191}
5192
5193/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005194 FUNCTION
5195 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005196
Arun Menon906de572013-06-18 17:01:40 -07005197 DESCRIPTION
5198 This routine is used to push the encoded video frames to
5199 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005200
Arun Menon906de572013-06-18 17:01:40 -07005201 PARAMETERS
5202 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005203
Arun Menon906de572013-06-18 17:01:40 -07005204 RETURN VALUE
5205 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005206
Arun Menon906de572013-06-18 17:01:40 -07005207 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005208OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005209 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005210{
Arun Menon906de572013-06-18 17:01:40 -07005211 int push_cnt = 0,i=0;
5212 unsigned nPortIndex = 0;
5213 OMX_ERRORTYPE ret = OMX_ErrorNone;
5214 struct vdec_input_frameinfo frameinfo;
5215 struct vdec_bufferpayload *temp_buffer;
5216 struct vdec_seqheader seq_header;
5217 bool port_setting_changed = true;
5218 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005219
Arun Menon906de572013-06-18 17:01:40 -07005220 /*Should we generate a Aync error event*/
5221 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
5222 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5223 return OMX_ErrorBadParameter;
5224 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005225
Arun Menon906de572013-06-18 17:01:40 -07005226 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005227
Arun Menon906de572013-06-18 17:01:40 -07005228 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
5229 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5230 nPortIndex);
5231 return OMX_ErrorBadParameter;
5232 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005233
Arun Menon906de572013-06-18 17:01:40 -07005234 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005235
Arun Menon906de572013-06-18 17:01:40 -07005236 /* return zero length and not an EOS buffer */
5237 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5238 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
5239 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5240 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5241 OMX_COMPONENT_GENERATE_EBD);
5242 return OMX_ErrorNone;
5243 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005244
5245
Arun Menon906de572013-06-18 17:01:40 -07005246 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5247 mp4StreamType psBits;
5248 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5249 psBits.numBytes = buffer->nFilledLen;
5250 mp4_headerparser.parseHeader(&psBits);
5251 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5252 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5253 if (not_coded_vop) {
5254 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
5255 buffer->nFilledLen,frame_count);
5256 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
5257 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5258 not_coded_vop = false;
5259 buffer->nFilledLen = 0;
5260 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005261 }
5262 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005263
Arun Menon906de572013-06-18 17:01:40 -07005264 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005265
Arun Menon906de572013-06-18 17:01:40 -07005266 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005267
Arun Menon906de572013-06-18 17:01:40 -07005268 ) {
5269 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5270 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5271 OMX_COMPONENT_GENERATE_EBD);
5272 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005273 }
5274
Arun Menon906de572013-06-18 17:01:40 -07005275 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005276
Arun Menon906de572013-06-18 17:01:40 -07005277 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) {
5278 return OMX_ErrorBadParameter;
5279 }
5280 /* If its first frame, H264 codec and reject is true, then parse the nal
5281 and get the profile. Based on this, reject the clip playback */
5282 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5283 m_reject_avc_1080p_mp) {
5284 first_frame = 1;
5285 DEBUG_PRINT_ERROR("\nParse nal to get the profile");
5286 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5287 NALU_TYPE_SPS);
5288 m_profile = h264_parser->get_profile();
5289 ret = is_video_session_supported();
5290 if (ret) {
5291 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5292 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5293 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5294 m_state = OMX_StateInvalid;
5295 return OMX_ErrorNone;
5296 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005297 }
5298
Arun Menon906de572013-06-18 17:01:40 -07005299 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5300 /*for use buffer we need to memcpy the data*/
5301 temp_buffer->buffer_len = buffer->nFilledLen;
5302
5303 if (input_use_buffer) {
5304 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5305 if (arbitrary_bytes) {
5306 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5307 } else {
5308 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5309 buffer->nFilledLen);
5310 }
5311 } else {
5312 return OMX_ErrorBadParameter;
5313 }
5314
5315 }
5316
5317 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5318 frameinfo.client_data = (void *) buffer;
5319 frameinfo.datalen = temp_buffer->buffer_len;
5320 frameinfo.flags = 0;
5321 frameinfo.offset = buffer->nOffset;
5322 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5323 frameinfo.pmem_offset = temp_buffer->offset;
5324 frameinfo.timestamp = buffer->nTimeStamp;
5325 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5326 DEBUG_PRINT_LOW("ETB: dmx enabled");
5327 if (m_demux_entries == 0) {
5328 extract_demux_addr_offsets(buffer);
5329 }
5330
5331 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5332 handle_demux_data(buffer);
5333 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5334 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5335 } else {
5336 frameinfo.desc_addr = NULL;
5337 frameinfo.desc_size = 0;
5338 }
5339 if (!arbitrary_bytes) {
5340 frameinfo.flags |= buffer->nFlags;
5341 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005342
5343#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005344 if (m_debug_timestamp) {
5345 if (arbitrary_bytes) {
5346 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5347 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5348 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5349 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5350 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5351 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005352 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005353#endif
5354
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005355log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005356
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005357if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005358 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5359 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5360 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005361
Arun Menon906de572013-06-18 17:01:40 -07005362 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5363 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5364 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5365 h264_scratch.nFilledLen = 0;
5366 nal_count = 0;
5367 look_ahead_nal = false;
5368 frame_count = 0;
5369 if (m_frame_parser.mutils)
5370 m_frame_parser.mutils->initialize_frame_checking_environment();
5371 m_frame_parser.flush();
5372 h264_last_au_ts = LLONG_MAX;
5373 h264_last_au_flags = 0;
5374 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5375 m_demux_entries = 0;
5376 }
5377 struct v4l2_buffer buf;
5378 struct v4l2_plane plane;
5379 memset( (void *)&buf, 0, sizeof(buf));
5380 memset( (void *)&plane, 0, sizeof(plane));
5381 int rc;
5382 unsigned long print_count;
5383 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005384 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Arun Menon906de572013-06-18 17:01:40 -07005385 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
5386 }
5387 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5388 buf.index = nPortIndex;
5389 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5390 buf.memory = V4L2_MEMORY_USERPTR;
5391 plane.bytesused = temp_buffer->buffer_len;
5392 plane.length = drv_ctx.ip_buf.buffer_size;
5393 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5394 (unsigned long)temp_buffer->offset;
5395 plane.reserved[0] = temp_buffer->pmem_fd;
5396 plane.reserved[1] = temp_buffer->offset;
5397 plane.data_offset = 0;
5398 buf.m.planes = &plane;
5399 buf.length = 1;
5400 if (frameinfo.timestamp >= LLONG_MAX) {
5401 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5402 }
5403 //assumption is that timestamp is in milliseconds
5404 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5405 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5406 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5407 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005408
Arun Menon906de572013-06-18 17:01:40 -07005409 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5410 if (rc) {
5411 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5412 return OMX_ErrorHardware;
5413 }
5414 if (!streaming[OUTPUT_PORT]) {
5415 enum v4l2_buf_type buf_type;
5416 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005417
Arun Menon906de572013-06-18 17:01:40 -07005418 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005419 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
Arun Menon906de572013-06-18 17:01:40 -07005420 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5421 if (!ret) {
5422 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
5423 streaming[OUTPUT_PORT] = true;
5424 } else {
5425 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
5426 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5427 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5428 OMX_COMPONENT_GENERATE_EBD);
5429 return OMX_ErrorBadParameter;
5430 }
5431 }
5432 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5433 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5434 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005435
Arun Menon906de572013-06-18 17:01:40 -07005436 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005437}
5438
5439/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005440 FUNCTION
5441 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005442
Arun Menon906de572013-06-18 17:01:40 -07005443 DESCRIPTION
5444 IL client uses this method to release the frame buffer
5445 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005446
Arun Menon906de572013-06-18 17:01:40 -07005447 PARAMETERS
5448 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005449
Arun Menon906de572013-06-18 17:01:40 -07005450 RETURN VALUE
5451 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005452
Arun Menon906de572013-06-18 17:01:40 -07005453 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005454OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005455 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005456{
5457
Arun Menon906de572013-06-18 17:01:40 -07005458 if (m_state == OMX_StateInvalid) {
5459 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5460 return OMX_ErrorInvalidState;
5461 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005462
Arun Menon906de572013-06-18 17:01:40 -07005463 if (!m_out_bEnabled) {
5464 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5465 return OMX_ErrorIncorrectStateOperation;
5466 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005467
Arun Menon906de572013-06-18 17:01:40 -07005468 if (buffer == NULL ||
5469 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) {
5470 return OMX_ErrorBadParameter;
5471 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005472
Arun Menon906de572013-06-18 17:01:40 -07005473 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
5474 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
5475 return OMX_ErrorBadPortIndex;
5476 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005477
Arun Menon906de572013-06-18 17:01:40 -07005478 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5479 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5480 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005481}
5482/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005483 FUNCTION
5484 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005485
Arun Menon906de572013-06-18 17:01:40 -07005486 DESCRIPTION
5487 IL client uses this method to release the frame buffer
5488 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005489
Arun Menon906de572013-06-18 17:01:40 -07005490 PARAMETERS
5491 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005492
Arun Menon906de572013-06-18 17:01:40 -07005493 RETURN VALUE
5494 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005495
Arun Menon906de572013-06-18 17:01:40 -07005496 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005497OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005498 OMX_IN OMX_HANDLETYPE hComp,
5499 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005500{
Arun Menon906de572013-06-18 17:01:40 -07005501 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5502 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5503 unsigned nPortIndex = 0;
5504 struct vdec_fillbuffer_cmd fillbuffer;
5505 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5506 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005507
Arun Menon906de572013-06-18 17:01:40 -07005508 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005509
Arun Menon906de572013-06-18 17:01:40 -07005510 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5511 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005512
Arun Menon906de572013-06-18 17:01:40 -07005513 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5514 bufferAdd, bufferAdd->pBuffer);
5515 /*Return back the output buffer to client*/
5516 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
5517 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5518 buffer->nFilledLen = 0;
5519 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5520 return OMX_ErrorNone;
5521 }
5522 pending_output_buffers++;
5523 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5524 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5525 if (ptr_respbuffer) {
5526 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5527 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005528
Arun Menon906de572013-06-18 17:01:40 -07005529 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5530 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5531 buffer->nFilledLen = 0;
5532 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5533 pending_output_buffers--;
5534 return OMX_ErrorBadParameter;
5535 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005536
Arun Menon906de572013-06-18 17:01:40 -07005537 int rc = 0;
5538 struct v4l2_buffer buf;
5539 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5540 memset( (void *)&buf, 0, sizeof(buf));
5541 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5542 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005543
Arun Menon906de572013-06-18 17:01:40 -07005544 buf.index = nPortIndex;
5545 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5546 buf.memory = V4L2_MEMORY_USERPTR;
5547 plane[0].bytesused = buffer->nFilledLen;
5548 plane[0].length = drv_ctx.op_buf.buffer_size;
5549 plane[0].m.userptr =
5550 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5551 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5552 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5553 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5554 plane[0].data_offset = 0;
5555 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5556 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5557 plane[extra_idx].bytesused = 0;
5558 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5559 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 -07005560#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005561 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005562#endif
Arun Menon906de572013-06-18 17:01:40 -07005563 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5564 plane[extra_idx].data_offset = 0;
5565 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5566 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5567 return OMX_ErrorBadParameter;
5568 }
5569 buf.m.planes = plane;
5570 buf.length = drv_ctx.num_planes;
5571 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5572 if (rc) {
5573 /*TODO: How to handle this case */
5574 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5575 }
Arun Menon906de572013-06-18 17:01:40 -07005576return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005577}
5578
5579/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005580 FUNCTION
5581 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005582
Arun Menon906de572013-06-18 17:01:40 -07005583 DESCRIPTION
5584 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005585
Arun Menon906de572013-06-18 17:01:40 -07005586 PARAMETERS
5587 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005588
Arun Menon906de572013-06-18 17:01:40 -07005589 RETURN VALUE
5590 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005591
Arun Menon906de572013-06-18 17:01:40 -07005592 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005593OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005594 OMX_IN OMX_CALLBACKTYPE* callbacks,
5595 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005596{
5597
Arun Menon906de572013-06-18 17:01:40 -07005598 m_cb = *callbacks;
5599 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5600 m_cb.EventHandler,m_cb.FillBufferDone);
5601 m_app_data = appData;
5602 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005603}
5604
5605/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005606 FUNCTION
5607 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005608
Arun Menon906de572013-06-18 17:01:40 -07005609 DESCRIPTION
5610 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005611
Arun Menon906de572013-06-18 17:01:40 -07005612 PARAMETERS
5613 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005614
Arun Menon906de572013-06-18 17:01:40 -07005615 RETURN VALUE
5616 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005617
Arun Menon906de572013-06-18 17:01:40 -07005618 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005619OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5620{
5621#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005622 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005623 delete iDivXDrmDecrypt;
5624 iDivXDrmDecrypt=NULL;
5625 }
5626#endif //_ANDROID_
5627
Shalaj Jain286b0062013-02-21 20:35:48 -08005628 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005629 if (OMX_StateLoaded != m_state) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005630 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
Arun Menon906de572013-06-18 17:01:40 -07005631 m_state);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005632 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005633 } else {
5634 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005635 }
5636
5637 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005638 if (m_out_mem_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005639 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005640 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5641 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005642 }
5643#ifdef _ANDROID_ICS_
5644 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5645#endif
5646 }
5647
5648 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005649 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005650 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005651 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5652 if (m_inp_mem_ptr)
5653 free_input_buffer (i,&m_inp_mem_ptr[i]);
5654 else
5655 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005656 }
5657 }
5658 free_input_buffer_header();
5659 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005660 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005661 free(h264_scratch.pBuffer);
5662 h264_scratch.pBuffer = NULL;
5663 }
5664
Arun Menon906de572013-06-18 17:01:40 -07005665 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005666 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005667 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005668 }
5669
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07005670 if (m_frame_parser.mutils) {
5671 DEBUG_PRINT_LOW("\n Free utils parser");
5672 delete (m_frame_parser.mutils);
5673 m_frame_parser.mutils = NULL;
5674 }
5675
Arun Menon906de572013-06-18 17:01:40 -07005676 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005677 free(m_platform_list);
5678 m_platform_list = NULL;
5679 }
Arun Menon906de572013-06-18 17:01:40 -07005680 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005681 free(m_vendor_config.pData);
5682 m_vendor_config.pData = NULL;
5683 }
5684
5685 // Reset counters in mesg queues
5686 m_ftb_q.m_size=0;
5687 m_cmd_q.m_size=0;
5688 m_etb_q.m_size=0;
5689 m_ftb_q.m_read = m_ftb_q.m_write =0;
5690 m_cmd_q.m_read = m_cmd_q.m_write =0;
5691 m_etb_q.m_read = m_etb_q.m_write =0;
5692#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005693 if (m_debug_timestamp) {
5694 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005695 }
5696#endif
5697
5698 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
5699 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07005700 // NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005701 DEBUG_PRINT_HIGH("\n Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07005702
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005703 if (m_debug.infile) {
5704 fclose(m_debug.infile);
5705 m_debug.infile = NULL;
5706 }
5707 if (m_debug.outfile) {
5708 fclose(m_debug.outfile);
5709 m_debug.outfile = NULL;
5710 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005711#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07005712 if (outputExtradataFile)
5713 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005714#endif
Arun Menon906de572013-06-18 17:01:40 -07005715 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
5716 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005717}
5718
5719/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005720 FUNCTION
5721 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07005722
Arun Menon906de572013-06-18 17:01:40 -07005723 DESCRIPTION
5724 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005725
Arun Menon906de572013-06-18 17:01:40 -07005726 PARAMETERS
5727 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005728
Arun Menon906de572013-06-18 17:01:40 -07005729 RETURN VALUE
5730 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005731
Arun Menon906de572013-06-18 17:01:40 -07005732 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005733OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005734 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5735 OMX_IN OMX_U32 port,
5736 OMX_IN OMX_PTR appData,
5737 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005738{
Arun Menon906de572013-06-18 17:01:40 -07005739 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
5740 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
5741 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005742
5743#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005744 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
5745 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005746#else
Arun Menon906de572013-06-18 17:01:40 -07005747 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005748#endif
Arun Menon906de572013-06-18 17:01:40 -07005749 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
5750 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
5751 DEBUG_PRINT_ERROR("\n ");
5752 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005753#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005754 if (m_display_id == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005755 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
5756 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005757 }
5758 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
5759 eglGetProcAddress("eglQueryImageKHR");
5760 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
5761 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
5762 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005763#else //with OMX test app
5764 struct temp_egl {
5765 int pmem_fd;
5766 int offset;
5767 };
5768 struct temp_egl *temp_egl_id = NULL;
5769 void * pmemPtr = (void *) eglImage;
5770 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07005771 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005772 fd = temp_egl_id->pmem_fd;
5773 offset = temp_egl_id->offset;
5774 }
5775#endif
5776 if (fd < 0) {
5777 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
5778 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005779 }
5780 pmem_info.pmem_fd = (OMX_U32) fd;
5781 pmem_info.offset = (OMX_U32) offset;
5782 pmem_entry.entry = (void *) &pmem_info;
5783 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5784 pmem_list.entryList = &pmem_entry;
5785 pmem_list.nEntries = 1;
5786 ouput_egl_buffers = true;
5787 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
5788 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
5789 (OMX_U8 *)pmemPtr)) {
5790 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
5791 return OMX_ErrorInsufficientResources;
5792 }
5793 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005794}
5795
5796/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005797 FUNCTION
5798 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07005799
Arun Menon906de572013-06-18 17:01:40 -07005800 DESCRIPTION
5801 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005802
Arun Menon906de572013-06-18 17:01:40 -07005803 PARAMETERS
5804 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005805
Arun Menon906de572013-06-18 17:01:40 -07005806 RETURN VALUE
5807 OMX Error None if everything is successful.
5808 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005809OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005810 OMX_OUT OMX_U8* role,
5811 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005812{
Arun Menon906de572013-06-18 17:01:40 -07005813 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005814
Arun Menon906de572013-06-18 17:01:40 -07005815 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
5816 if ((0 == index) && role) {
5817 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
5818 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5819 } else {
5820 eRet = OMX_ErrorNoMore;
5821 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005822 }
Arun Menon906de572013-06-18 17:01:40 -07005823 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
5824 if ((0 == index) && role) {
5825 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
5826 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5827 } else {
5828 eRet = OMX_ErrorNoMore;
5829 }
5830 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
5831 if ((0 == index) && role) {
5832 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
5833 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5834 } else {
5835 DEBUG_PRINT_LOW("\n No more roles \n");
5836 eRet = OMX_ErrorNoMore;
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 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
5841 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
5842 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07005843
Shalaj Jain273b3e02012-06-22 19:08:03 -07005844 {
Arun Menon906de572013-06-18 17:01:40 -07005845 if ((0 == index) && role) {
5846 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
5847 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5848 } else {
5849 DEBUG_PRINT_LOW("\n No more roles \n");
5850 eRet = OMX_ErrorNoMore;
5851 }
5852 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
5853 if ((0 == index) && role) {
5854 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
5855 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5856 } else {
5857 DEBUG_PRINT_LOW("\n No more roles \n");
5858 eRet = OMX_ErrorNoMore;
5859 }
5860 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
5861 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
5862 ) {
5863 if ((0 == index) && role) {
5864 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
5865 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5866 } else {
5867 DEBUG_PRINT_LOW("\n No more roles \n");
5868 eRet = OMX_ErrorNoMore;
5869 }
5870 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
5871 if ((0 == index) && role) {
5872 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
5873 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5874 } else {
5875 DEBUG_PRINT_LOW("\n No more roles \n");
5876 eRet = OMX_ErrorNoMore;
5877 }
5878 } else {
5879 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
5880 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005881 }
Arun Menon906de572013-06-18 17:01:40 -07005882 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005883}
5884
5885
5886
5887
5888/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005889 FUNCTION
5890 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07005891
Arun Menon906de572013-06-18 17:01:40 -07005892 DESCRIPTION
5893 Checks if entire buffer pool is allocated by IL Client or not.
5894 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005895
Arun Menon906de572013-06-18 17:01:40 -07005896 PARAMETERS
5897 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005898
Arun Menon906de572013-06-18 17:01:40 -07005899 RETURN VALUE
5900 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005901
Arun Menon906de572013-06-18 17:01:40 -07005902 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005903bool omx_vdec::allocate_done(void)
5904{
Arun Menon906de572013-06-18 17:01:40 -07005905 bool bRet = false;
5906 bool bRet_In = false;
5907 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005908
Arun Menon906de572013-06-18 17:01:40 -07005909 bRet_In = allocate_input_done();
5910 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005911
Arun Menon906de572013-06-18 17:01:40 -07005912 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005913 bRet = true;
5914 }
Arun Menon906de572013-06-18 17:01:40 -07005915
5916 return bRet;
5917}
5918/* ======================================================================
5919 FUNCTION
5920 omx_vdec::AllocateInputDone
5921
5922 DESCRIPTION
5923 Checks if I/P buffer pool is allocated by IL Client or not.
5924
5925 PARAMETERS
5926 None.
5927
5928 RETURN VALUE
5929 true/false.
5930
5931 ========================================================================== */
5932bool omx_vdec::allocate_input_done(void)
5933{
5934 bool bRet = false;
5935 unsigned i=0;
5936
5937 if (m_inp_mem_ptr == NULL) {
5938 return bRet;
5939 }
5940 if (m_inp_mem_ptr ) {
5941 for (; i<drv_ctx.ip_buf.actualcount; i++) {
5942 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
5943 break;
5944 }
5945 }
5946 }
5947 if (i == drv_ctx.ip_buf.actualcount) {
5948 bRet = true;
5949 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
5950 }
5951 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
5952 m_inp_bPopulated = OMX_TRUE;
5953 }
5954 return bRet;
5955}
5956/* ======================================================================
5957 FUNCTION
5958 omx_vdec::AllocateOutputDone
5959
5960 DESCRIPTION
5961 Checks if entire O/P buffer pool is allocated by IL Client or not.
5962
5963 PARAMETERS
5964 None.
5965
5966 RETURN VALUE
5967 true/false.
5968
5969 ========================================================================== */
5970bool omx_vdec::allocate_output_done(void)
5971{
5972 bool bRet = false;
5973 unsigned j=0;
5974
5975 if (m_out_mem_ptr == NULL) {
5976 return bRet;
5977 }
5978
5979 if (m_out_mem_ptr) {
5980 for (; j < drv_ctx.op_buf.actualcount; j++) {
5981 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
5982 break;
5983 }
5984 }
5985 }
5986
5987 if (j == drv_ctx.op_buf.actualcount) {
5988 bRet = true;
5989 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
5990 if (m_out_bEnabled)
5991 m_out_bPopulated = OMX_TRUE;
5992 }
5993
5994 return bRet;
5995}
5996
5997/* ======================================================================
5998 FUNCTION
5999 omx_vdec::ReleaseDone
6000
6001 DESCRIPTION
6002 Checks if IL client has released all the buffers.
6003
6004 PARAMETERS
6005 None.
6006
6007 RETURN VALUE
6008 true/false
6009
6010 ========================================================================== */
6011bool omx_vdec::release_done(void)
6012{
6013 bool bRet = false;
6014
6015 if (release_input_done()) {
6016 if (release_output_done()) {
6017 bRet = true;
6018 }
6019 }
6020 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006021}
6022
6023
6024/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006025 FUNCTION
6026 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006027
Arun Menon906de572013-06-18 17:01:40 -07006028 DESCRIPTION
6029 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006030
Arun Menon906de572013-06-18 17:01:40 -07006031 PARAMETERS
6032 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006033
Arun Menon906de572013-06-18 17:01:40 -07006034 RETURN VALUE
6035 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006036
Arun Menon906de572013-06-18 17:01:40 -07006037 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006038bool omx_vdec::release_output_done(void)
6039{
Arun Menon906de572013-06-18 17:01:40 -07006040 bool bRet = false;
6041 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006042
Arun Menon906de572013-06-18 17:01:40 -07006043 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6044 if (m_out_mem_ptr) {
6045 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6046 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6047 break;
6048 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006049 }
Arun Menon906de572013-06-18 17:01:40 -07006050 if (j == drv_ctx.op_buf.actualcount) {
6051 m_out_bm_count = 0;
6052 bRet = true;
6053 }
6054 } else {
6055 m_out_bm_count = 0;
6056 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006057 }
Arun Menon906de572013-06-18 17:01:40 -07006058 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006059}
6060/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006061 FUNCTION
6062 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006063
Arun Menon906de572013-06-18 17:01:40 -07006064 DESCRIPTION
6065 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006066
Arun Menon906de572013-06-18 17:01:40 -07006067 PARAMETERS
6068 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006069
Arun Menon906de572013-06-18 17:01:40 -07006070 RETURN VALUE
6071 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006072
Arun Menon906de572013-06-18 17:01:40 -07006073 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006074bool omx_vdec::release_input_done(void)
6075{
Arun Menon906de572013-06-18 17:01:40 -07006076 bool bRet = false;
6077 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006078
Arun Menon906de572013-06-18 17:01:40 -07006079 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6080 if (m_inp_mem_ptr) {
6081 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6082 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6083 break;
6084 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006085 }
Arun Menon906de572013-06-18 17:01:40 -07006086 if (j==drv_ctx.ip_buf.actualcount) {
6087 bRet = true;
6088 }
6089 } else {
6090 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006091 }
Arun Menon906de572013-06-18 17:01:40 -07006092 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006093}
6094
6095OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006096 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006097{
Arun Menon906de572013-06-18 17:01:40 -07006098 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6099 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) {
6100 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6101 return OMX_ErrorBadParameter;
6102 } else if (output_flush_progress) {
6103 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6104 buffer->nFilledLen = 0;
6105 buffer->nTimeStamp = 0;
6106 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6107 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6108 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006109 }
6110
Arun Menon906de572013-06-18 17:01:40 -07006111 if (m_debug_extradata) {
6112 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
6113 DEBUG_PRINT_HIGH("\n");
6114 DEBUG_PRINT_HIGH("***************************************************\n");
6115 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
6116 DEBUG_PRINT_HIGH("***************************************************\n");
6117 }
6118
6119 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
6120 DEBUG_PRINT_HIGH("\n");
6121 DEBUG_PRINT_HIGH("***************************************************\n");
6122 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
6123 DEBUG_PRINT_HIGH("***************************************************\n");
6124 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006125 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006126
6127
Arun Menon906de572013-06-18 17:01:40 -07006128 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6129 buffer, buffer->pBuffer);
6130 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006131
Arun Menon906de572013-06-18 17:01:40 -07006132 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6133 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6134 if (!output_flush_progress)
6135 post_event((unsigned)NULL, (unsigned)NULL,
6136 OMX_COMPONENT_GENERATE_EOS_DONE);
6137
6138 if (psource_frame) {
6139 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6140 psource_frame = NULL;
6141 }
6142 if (pdest_frame) {
6143 pdest_frame->nFilledLen = 0;
6144 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6145 (unsigned)NULL);
6146 pdest_frame = NULL;
6147 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006148 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006149
Arun Menon906de572013-06-18 17:01:40 -07006150 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006151 log_output_buffers(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006152
Arun Menon906de572013-06-18 17:01:40 -07006153 /* For use buffer we need to copy the data */
6154 if (!output_flush_progress) {
6155 /* This is the error check for non-recoverable errros */
6156 bool is_duplicate_ts_valid = true;
6157 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006158
Arun Menon906de572013-06-18 17:01:40 -07006159 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6160 output_capability == V4L2_PIX_FMT_MPEG2 ||
6161 output_capability == V4L2_PIX_FMT_DIVX ||
6162 output_capability == V4L2_PIX_FMT_DIVX_311)
6163 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006164
Arun Menon906de572013-06-18 17:01:40 -07006165 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6166 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6167 if (mbaff) {
6168 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306169 }
Arun Menon906de572013-06-18 17:01:40 -07006170 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306171
Arun Menon906de572013-06-18 17:01:40 -07006172 if (buffer->nFilledLen > 0) {
6173 time_stamp_dts.get_next_timestamp(buffer,
6174 is_interlaced && is_duplicate_ts_valid);
6175 if (m_debug_timestamp) {
6176 {
6177 OMX_TICKS expected_ts = 0;
6178 m_timestamp_list.pop_min_ts(expected_ts);
6179 if (is_interlaced && is_duplicate_ts_valid) {
6180 m_timestamp_list.pop_min_ts(expected_ts);
6181 }
6182 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6183 buffer->nTimeStamp, expected_ts);
6184
6185 if (buffer->nTimeStamp != expected_ts) {
6186 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6187 }
6188 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306189 }
Arun Menon906de572013-06-18 17:01:40 -07006190 } else {
6191 m_inp_err_count++;
6192 time_stamp_dts.remove_time_stamp(
6193 buffer->nTimeStamp,
6194 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306195 }
Arun Menon906de572013-06-18 17:01:40 -07006196
6197
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006198 }
Arun Menon906de572013-06-18 17:01:40 -07006199 if (m_cb.FillBufferDone) {
6200 if (buffer->nFilledLen > 0) {
6201 handle_extradata(buffer);
6202 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6203 set_frame_rate(buffer->nTimeStamp);
6204 else if (arbitrary_bytes)
6205 adjust_timestamp(buffer->nTimeStamp);
6206 if (perf_flag) {
6207 if (!proc_frms) {
6208 dec_time.stop();
6209 latency = dec_time.processing_time_us() - latency;
6210 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6211 dec_time.start();
6212 fps_metrics.start();
6213 }
6214 proc_frms++;
6215 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6216 OMX_U64 proc_time = 0;
6217 fps_metrics.stop();
6218 proc_time = fps_metrics.processing_time_us();
6219 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006220 proc_frms, (float)proc_time / 1e6,
6221 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006222 proc_frms = 0;
6223 }
6224 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006225
6226#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006227 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006228
Arun Menon906de572013-06-18 17:01:40 -07006229 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6230 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6231 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6232 buffer->nFilledLen + 3)&(~3));
6233 while (p_extra &&
6234 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
6235 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6236 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6237 if (p_extra->eType == OMX_ExtraDataNone) {
6238 break;
6239 }
6240 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6241 }
6242 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006243#endif
Arun Menon906de572013-06-18 17:01:40 -07006244 }
6245 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6246 prev_ts = LLONG_MAX;
6247 rst_prev_ts = true;
6248 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006249
Arun Menon906de572013-06-18 17:01:40 -07006250 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6251 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6252 buffer->pPlatformPrivate)->entryList->entry;
6253 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006254 OMX_BUFFERHEADERTYPE *il_buffer;
6255 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6256 if (il_buffer)
6257 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6258 else {
6259 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6260 return OMX_ErrorBadParameter;
6261 }
6262 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
6263 } else {
6264 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006265 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006266
Arun Menon906de572013-06-18 17:01:40 -07006267 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006268}
6269
6270OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006271 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006272{
6273
Arun Menon906de572013-06-18 17:01:40 -07006274 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006275 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006276 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006277 }
6278
6279 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006280 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006281 pending_input_buffers--;
6282
Arun Menon906de572013-06-18 17:01:40 -07006283 if (arbitrary_bytes) {
6284 if (pdest_frame == NULL && input_flush_progress == false) {
6285 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6286 pdest_frame = buffer;
6287 buffer->nFilledLen = 0;
6288 buffer->nTimeStamp = LLONG_MAX;
6289 push_input_buffer (hComp);
6290 } else {
6291 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6292 buffer->nFilledLen = 0;
6293 if (!m_input_free_q.insert_entry((unsigned)buffer,
6294 (unsigned)NULL, (unsigned)NULL)) {
6295 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6296 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006297 }
Arun Menon906de572013-06-18 17:01:40 -07006298 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006299 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006300 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006301 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6302 }
6303 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6304 }
6305 return OMX_ErrorNone;
6306}
6307
Shalaj Jain273b3e02012-06-22 19:08:03 -07006308int omx_vdec::async_message_process (void *context, void* message)
6309{
Arun Menon906de572013-06-18 17:01:40 -07006310 omx_vdec* omx = NULL;
6311 struct vdec_msginfo *vdec_msg = NULL;
6312 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6313 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6314 struct vdec_output_frameinfo *output_respbuf = NULL;
6315 int rc=1;
6316 if (context == NULL || message == NULL) {
6317 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6318 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006319 }
Arun Menon906de572013-06-18 17:01:40 -07006320 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006321
Arun Menon906de572013-06-18 17:01:40 -07006322 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006323
Arun Menon906de572013-06-18 17:01:40 -07006324 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006325
Arun Menon906de572013-06-18 17:01:40 -07006326 case VDEC_MSG_EVT_HW_ERROR:
6327 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6328 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6329 break;
6330
6331 case VDEC_MSG_RESP_START_DONE:
6332 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6333 OMX_COMPONENT_GENERATE_START_DONE);
6334 break;
6335
6336 case VDEC_MSG_RESP_STOP_DONE:
6337 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6338 OMX_COMPONENT_GENERATE_STOP_DONE);
6339 break;
6340
6341 case VDEC_MSG_RESP_RESUME_DONE:
6342 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6343 OMX_COMPONENT_GENERATE_RESUME_DONE);
6344 break;
6345
6346 case VDEC_MSG_RESP_PAUSE_DONE:
6347 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6348 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6349 break;
6350
6351 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6352 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6353 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6354 break;
6355 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6356 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6357 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6358 break;
6359 case VDEC_MSG_RESP_INPUT_FLUSHED:
6360 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6361
6362 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6363 vdec_msg->msgdata.input_frame_clientdata; */
6364
6365 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6366 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6367 if (omxhdr == NULL ||
6368 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) {
6369 omxhdr = NULL;
6370 vdec_msg->status_code = VDEC_S_EFATAL;
6371 }
6372 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6373 DEBUG_PRINT_HIGH("Unsupported input");
6374 omx->omx_report_error ();
6375 }
6376 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6377 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6378 }
6379 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6380 OMX_COMPONENT_GENERATE_EBD);
6381 break;
6382 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6383 int64_t *timestamp;
6384 timestamp = (int64_t *) malloc(sizeof(int64_t));
6385 if (timestamp) {
6386 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6387 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6388 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6389 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6390 vdec_msg->msgdata.output_frame.time_stamp);
6391 }
6392 break;
6393 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6394 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6395
6396 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6397 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6398 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6399 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6400 vdec_msg->msgdata.output_frame.pic_type);
6401
6402 if (omxhdr && omxhdr->pOutputPortPrivate &&
6403 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6404 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6405 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) {
6406 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6407 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6408 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6409 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6410 omxhdr->nFlags = 0;
6411
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006412 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006413 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6414 //rc = -1;
6415 }
6416 if (omxhdr->nFilledLen) {
6417 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6418 }
6419 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6420 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6421 } else {
6422 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6423 }
6424 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6425 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6426 }
6427 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6428 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6429 }
6430 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6431 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006432 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006433 omx->time_stamp_dts.remove_time_stamp(
6434 omxhdr->nTimeStamp,
6435 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6436 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006437 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6438 OMX_COMPONENT_GENERATE_FTB);
6439 break;
6440 }
6441 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6442 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6443 }
6444 vdec_msg->msgdata.output_frame.bufferaddr =
6445 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6446 int format_notably_changed = 0;
6447 if (omxhdr->nFilledLen &&
6448 (omxhdr->nFilledLen != omx->prev_n_filled_len)) {
6449 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6450 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6451 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
6452 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6453 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6454 format_notably_changed = 1;
6455 }
6456 }
6457 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6458 vdec_msg->msgdata.output_frame.framesize.left)
6459 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6460 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6461 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6462 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6463 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6464 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6465 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6466 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
6467 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6468 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6469 }
6470 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
6471 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6472 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006473 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6474 omx->drv_ctx.video_resolution.frame_width) {
6475 vdec_msg->msgdata.output_frame.framesize.left = 0;
6476 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6477 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6478 }
6479 }
6480 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6481 omx->drv_ctx.video_resolution.frame_height) {
6482 vdec_msg->msgdata.output_frame.framesize.top = 0;
6483 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6484 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6485 }
6486 }
6487 DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d\n",
6488 vdec_msg->msgdata.output_frame.framesize.left,
6489 vdec_msg->msgdata.output_frame.framesize.top,
6490 vdec_msg->msgdata.output_frame.framesize.right,
6491 vdec_msg->msgdata.output_frame.framesize.bottom,
6492 omx->drv_ctx.video_resolution.frame_width,
6493 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006494 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6495 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6496 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6497 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6498 format_notably_changed = 1;
6499 }
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006500 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d\n",
6501 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6502 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006503 if (format_notably_changed) {
6504 if (omx->is_video_session_supported()) {
6505 omx->post_event (NULL, vdec_msg->status_code,
6506 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6507 } else {
6508 if (!omx->client_buffers.update_buffer_req()) {
6509 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6510 }
6511 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6512 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6513 }
6514 }
6515 if (omxhdr->nFilledLen)
6516 omx->prev_n_filled_len = omxhdr->nFilledLen;
6517
6518 output_respbuf = (struct vdec_output_frameinfo *)\
6519 omxhdr->pOutputPortPrivate;
6520 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6521 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6522 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6523 output_respbuf->pic_type = PICTURE_TYPE_I;
6524 }
6525 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6526 output_respbuf->pic_type = PICTURE_TYPE_P;
6527 }
6528 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6529 output_respbuf->pic_type = PICTURE_TYPE_B;
6530 }
6531
6532 if (omx->output_use_buffer)
6533 memcpy ( omxhdr->pBuffer, (void *)
6534 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6535 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6536 vdec_msg->msgdata.output_frame.len);
6537 } else
6538 omxhdr->nFilledLen = 0;
6539 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6540 OMX_COMPONENT_GENERATE_FBD);
6541 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6542 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6543 OMX_COMPONENT_GENERATE_EOS_DONE);
6544 else
6545 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6546 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6547 break;
6548 case VDEC_MSG_EVT_CONFIG_CHANGED:
6549 DEBUG_PRINT_HIGH("\n Port settings changed");
6550 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6551 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6552 break;
6553 default:
6554 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006555 }
Arun Menon906de572013-06-18 17:01:40 -07006556 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006557}
6558
6559OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006560 OMX_HANDLETYPE hComp,
6561 OMX_BUFFERHEADERTYPE *buffer
6562 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006563{
Arun Menon906de572013-06-18 17:01:40 -07006564 unsigned address,p2,id;
6565 DEBUG_PRINT_LOW("\n Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006566
Arun Menon906de572013-06-18 17:01:40 -07006567 if (buffer == NULL) {
6568 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006569 }
Arun Menon906de572013-06-18 17:01:40 -07006570 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6571 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
6572 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6573
6574 /* return zero length and not an EOS buffer */
6575 /* return buffer if input flush in progress */
6576 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6577 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
6578 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
6579 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6580 return OMX_ErrorNone;
6581 }
6582
6583 if (psource_frame == NULL) {
6584 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
6585 psource_frame = buffer;
6586 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
6587 push_input_buffer (hComp);
6588 } else {
6589 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
6590 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6591 (unsigned)NULL)) {
6592 return OMX_ErrorBadParameter;
6593 }
6594 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006595
6596
Arun Menon906de572013-06-18 17:01:40 -07006597 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006598}
6599
6600OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6601{
Arun Menon906de572013-06-18 17:01:40 -07006602 unsigned address,p2,id;
6603 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006604
Arun Menon906de572013-06-18 17:01:40 -07006605 if (pdest_frame == NULL || psource_frame == NULL) {
6606 /*Check if we have a destination buffer*/
6607 if (pdest_frame == NULL) {
6608 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
6609 if (m_input_free_q.m_size) {
6610 m_input_free_q.pop_entry(&address,&p2,&id);
6611 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6612 pdest_frame->nFilledLen = 0;
6613 pdest_frame->nTimeStamp = LLONG_MAX;
6614 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
6615 }
6616 }
6617
6618 /*Check if we have a destination buffer*/
6619 if (psource_frame == NULL) {
6620 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
6621 if (m_input_pending_q.m_size) {
6622 m_input_pending_q.pop_entry(&address,&p2,&id);
6623 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
6624 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6625 psource_frame->nTimeStamp);
6626 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6627 psource_frame->nFlags,psource_frame->nFilledLen);
6628
6629 }
6630 }
6631
Shalaj Jain273b3e02012-06-22 19:08:03 -07006632 }
6633
Arun Menon906de572013-06-18 17:01:40 -07006634 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6635 switch (codec_type_parse) {
6636 case CODEC_TYPE_MPEG4:
6637 case CODEC_TYPE_H263:
6638 case CODEC_TYPE_MPEG2:
6639 ret = push_input_sc_codec(hComp);
6640 break;
6641 case CODEC_TYPE_H264:
6642 ret = push_input_h264(hComp);
6643 break;
6644 case CODEC_TYPE_VC1:
6645 ret = push_input_vc1(hComp);
6646 break;
6647 default:
6648 break;
6649 }
6650 if (ret != OMX_ErrorNone) {
6651 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
6652 omx_report_error ();
6653 break;
6654 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006655 }
6656
Arun Menon906de572013-06-18 17:01:40 -07006657 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006658}
6659
6660OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
6661{
Arun Menon906de572013-06-18 17:01:40 -07006662 OMX_U32 partial_frame = 1;
6663 OMX_BOOL generate_ebd = OMX_TRUE;
6664 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006665
Arun Menon906de572013-06-18 17:01:40 -07006666 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
6667 psource_frame,psource_frame->nTimeStamp);
6668 if (m_frame_parser.parse_sc_frame(psource_frame,
6669 pdest_frame,&partial_frame) == -1) {
6670 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
6671 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006672 }
Arun Menon906de572013-06-18 17:01:40 -07006673
6674 if (partial_frame == 0) {
6675 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
6676 pdest_frame->nFilledLen,psource_frame,frame_count);
6677
6678
6679 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
6680 /*First Parsed buffer will have only header Hence skip*/
6681 if (frame_count == 0) {
6682 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
6683
6684 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
6685 codec_type_parse == CODEC_TYPE_DIVX) {
6686 mp4StreamType psBits;
6687 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
6688 psBits.numBytes = pdest_frame->nFilledLen;
6689 mp4_headerparser.parseHeader(&psBits);
6690 }
6691
6692 frame_count++;
6693 } else {
6694 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6695 if (pdest_frame->nFilledLen) {
6696 /*Push the frame to the Decoder*/
6697 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6698 return OMX_ErrorBadParameter;
6699 }
6700 frame_count++;
6701 pdest_frame = NULL;
6702
6703 if (m_input_free_q.m_size) {
6704 m_input_free_q.pop_entry(&address,&p2,&id);
6705 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6706 pdest_frame->nFilledLen = 0;
6707 }
6708 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
6709 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
6710 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
6711 (unsigned)NULL);
6712 pdest_frame = NULL;
6713 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006714 }
Arun Menon906de572013-06-18 17:01:40 -07006715 } else {
6716 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
6717 /*Check if Destination Buffer is full*/
6718 if (pdest_frame->nAllocLen ==
6719 pdest_frame->nFilledLen + pdest_frame->nOffset) {
6720 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
6721 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006722 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006723 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006724
Arun Menon906de572013-06-18 17:01:40 -07006725 if (psource_frame->nFilledLen == 0) {
6726 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6727 if (pdest_frame) {
6728 pdest_frame->nFlags |= psource_frame->nFlags;
6729 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
6730 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6731 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6732 pdest_frame->nFilledLen,frame_count++);
6733 /*Push the frame to the Decoder*/
6734 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6735 return OMX_ErrorBadParameter;
6736 }
6737 frame_count++;
6738 pdest_frame = NULL;
6739 } else {
6740 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
6741 generate_ebd = OMX_FALSE;
6742 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006743 }
Arun Menon906de572013-06-18 17:01:40 -07006744 if (generate_ebd) {
6745 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
6746 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6747 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006748
Arun Menon906de572013-06-18 17:01:40 -07006749 if (m_input_pending_q.m_size) {
6750 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6751 m_input_pending_q.pop_entry(&address,&p2,&id);
6752 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6753 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6754 psource_frame->nTimeStamp);
6755 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6756 psource_frame->nFlags,psource_frame->nFilledLen);
6757 }
6758 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006759 }
Arun Menon906de572013-06-18 17:01:40 -07006760 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006761}
6762
6763OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
6764{
Arun Menon906de572013-06-18 17:01:40 -07006765 OMX_U32 partial_frame = 1;
6766 unsigned address = 0, p2 = 0, id = 0;
6767 OMX_BOOL isNewFrame = OMX_FALSE;
6768 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006769
Arun Menon906de572013-06-18 17:01:40 -07006770 if (h264_scratch.pBuffer == NULL) {
6771 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
6772 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006773 }
Arun Menon906de572013-06-18 17:01:40 -07006774 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
6775 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
6776 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
6777 if (h264_scratch.nFilledLen && look_ahead_nal) {
6778 look_ahead_nal = false;
6779 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6780 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006781 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6782 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6783 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Arun Menon906de572013-06-18 17:01:40 -07006784 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006785 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006786 } else {
6787 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006788 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006789 }
Arun Menon906de572013-06-18 17:01:40 -07006790 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07006791
6792 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
6793 in EOS flag getting associated with the destination
6794 */
6795 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
6796 pdest_frame->nFilledLen) {
6797 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
6798 generate_ebd = OMX_FALSE;
6799 }
6800
Arun Menon906de572013-06-18 17:01:40 -07006801 if (nal_length == 0) {
6802 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
6803 if (m_frame_parser.parse_sc_frame(psource_frame,
6804 &h264_scratch,&partial_frame) == -1) {
6805 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006806 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006807 }
Arun Menon906de572013-06-18 17:01:40 -07006808 } else {
6809 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
6810 if (m_frame_parser.parse_h264_nallength(psource_frame,
6811 &h264_scratch,&partial_frame) == -1) {
6812 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
6813 return OMX_ErrorBadParameter;
6814 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006815 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006816
Arun Menon906de572013-06-18 17:01:40 -07006817 if (partial_frame == 0) {
6818 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
6819 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
6820 nal_count++;
6821 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
6822 h264_scratch.nFlags = psource_frame->nFlags;
6823 } else {
6824 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
6825 if (h264_scratch.nFilledLen) {
6826 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
6827 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006828#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07006829 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6830 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
6831 h264_scratch.nFilledLen, NALU_TYPE_SEI);
6832 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
6833 // If timeinfo is present frame info from SEI is already processed
6834 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
6835 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006836#endif
Arun Menon906de572013-06-18 17:01:40 -07006837 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
6838 nal_count++;
6839 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
6840 pdest_frame->nTimeStamp = h264_last_au_ts;
6841 pdest_frame->nFlags = h264_last_au_flags;
6842#ifdef PANSCAN_HDLR
6843 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
6844 h264_parser->update_panscan_data(h264_last_au_ts);
6845#endif
6846 }
6847 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
6848 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
6849 h264_last_au_ts = h264_scratch.nTimeStamp;
6850 h264_last_au_flags = h264_scratch.nFlags;
6851#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
6852 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
6853 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
6854 if (!VALID_TS(h264_last_au_ts))
6855 h264_last_au_ts = ts_in_sei;
6856 }
6857#endif
6858 } else
6859 h264_last_au_ts = LLONG_MAX;
6860 }
6861
6862 if (!isNewFrame) {
6863 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6864 h264_scratch.nFilledLen) {
6865 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
6866 h264_scratch.nFilledLen);
6867 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6868 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6869 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6870 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
6871 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6872 h264_scratch.nFilledLen = 0;
6873 } else {
6874 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
6875 return OMX_ErrorBadParameter;
6876 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07006877 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07006878 look_ahead_nal = true;
6879 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
6880 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6881 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6882 pdest_frame->nFilledLen,frame_count++);
6883
6884 if (pdest_frame->nFilledLen == 0) {
6885 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
6886 look_ahead_nal = false;
6887 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6888 h264_scratch.nFilledLen) {
6889 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6890 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6891 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6892 h264_scratch.nFilledLen = 0;
6893 } else {
6894 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
6895 return OMX_ErrorBadParameter;
6896 }
6897 } else {
6898 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
6899 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
6900 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6901 }
6902 /*Push the frame to the Decoder*/
6903 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6904 return OMX_ErrorBadParameter;
6905 }
6906 //frame_count++;
6907 pdest_frame = NULL;
6908 if (m_input_free_q.m_size) {
6909 m_input_free_q.pop_entry(&address,&p2,&id);
6910 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6911 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
6912 pdest_frame->nFilledLen = 0;
6913 pdest_frame->nFlags = 0;
6914 pdest_frame->nTimeStamp = LLONG_MAX;
6915 }
6916 }
6917 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006918 }
Arun Menon906de572013-06-18 17:01:40 -07006919 } else {
6920 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
6921 /*Check if Destination Buffer is full*/
6922 if (h264_scratch.nAllocLen ==
6923 h264_scratch.nFilledLen + h264_scratch.nOffset) {
6924 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
6925 return OMX_ErrorStreamCorrupt;
6926 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006927 }
Arun Menon906de572013-06-18 17:01:40 -07006928
6929 if (!psource_frame->nFilledLen) {
6930 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
6931
6932 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6933 if (pdest_frame) {
6934 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
6935 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6936 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07006937 if(pdest_frame->nFilledLen == 0) {
6938 /* No residual frame from before, send whatever
6939 * we have left */
6940 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6941 h264_scratch.pBuffer, h264_scratch.nFilledLen);
6942 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6943 h264_scratch.nFilledLen = 0;
6944 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
6945 } else {
6946 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
6947 if(!isNewFrame) {
6948 /* Have a residual frame, but we know that the
6949 * AU in this frame is belonging to whatever
6950 * frame we had left over. So append it */
6951 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6952 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6953 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6954 h264_scratch.nFilledLen = 0;
6955 pdest_frame->nTimeStamp = h264_last_au_ts;
6956 } else {
6957 /* Completely new frame, let's just push what
6958 * we have now. The resulting EBD would trigger
6959 * another push */
6960 generate_ebd = OMX_FALSE;
6961 pdest_frame->nTimeStamp = h264_last_au_ts;
6962 h264_last_au_ts = h264_scratch.nTimeStamp;
6963 }
6964 }
Arun Menon906de572013-06-18 17:01:40 -07006965 } else {
6966 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
6967 return OMX_ErrorBadParameter;
6968 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07006969
6970 /* Iff we coalesced two buffers, inherit the flags of both bufs */
6971 if(generate_ebd == OMX_TRUE) {
6972 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
6973 }
Arun Menon906de572013-06-18 17:01:40 -07006974
6975 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
6976 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6977 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
6978#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
6979 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
6980 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
6981 if (!VALID_TS(pdest_frame->nTimeStamp))
6982 pdest_frame->nTimeStamp = ts_in_sei;
6983 }
6984#endif
6985 /*Push the frame to the Decoder*/
6986 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6987 return OMX_ErrorBadParameter;
6988 }
6989 frame_count++;
6990 pdest_frame = NULL;
6991 } else {
6992 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
6993 pdest_frame,h264_scratch.nFilledLen);
6994 generate_ebd = OMX_FALSE;
6995 }
6996 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006997 }
Arun Menon906de572013-06-18 17:01:40 -07006998 if (generate_ebd && !psource_frame->nFilledLen) {
6999 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7000 psource_frame = NULL;
7001 if (m_input_pending_q.m_size) {
7002 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7003 m_input_pending_q.pop_entry(&address,&p2,&id);
7004 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7005 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
7006 psource_frame->nFlags,psource_frame->nFilledLen);
7007 }
7008 }
7009 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007010}
7011
7012OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7013{
7014 OMX_U8 *buf, *pdest;
7015 OMX_U32 partial_frame = 1;
7016 OMX_U32 buf_len, dest_len;
7017
Arun Menon906de572013-06-18 17:01:40 -07007018 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007019 first_frame = 1;
7020 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
Arun Menon906de572013-06-18 17:01:40 -07007021 if (!m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007022 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7023 buf = psource_frame->pBuffer;
7024 buf_len = psource_frame->nFilledLen;
7025
7026 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007027 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007028 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007029 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007030 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007031 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007032 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7033 return OMX_ErrorStreamCorrupt;
7034 }
Arun Menon906de572013-06-18 17:01:40 -07007035 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007036 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7037 pdest_frame->nOffset;
7038 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007039 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007040
Arun Menon906de572013-06-18 17:01:40 -07007041 if (dest_len < m_vendor_config.nDataSize) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007042 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7043 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007044 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007045 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7046 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7047 }
7048 }
7049 }
7050
Arun Menon906de572013-06-18 17:01:40 -07007051 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007052 case VC1_AP:
7053 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007054 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007055 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7056 return OMX_ErrorBadParameter;
7057 }
Arun Menon906de572013-06-18 17:01:40 -07007058 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007059
7060 case VC1_SP_MP_RCV:
7061 default:
7062 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7063 return OMX_ErrorBadParameter;
7064 }
7065 return OMX_ErrorNone;
7066}
7067
David Ng38e2d232013-03-15 20:05:58 -07007068#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007069bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007070 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007071{
Arun Menon906de572013-06-18 17:01:40 -07007072 struct pmem_allocation allocation;
7073 allocation.size = buffer_size;
7074 allocation.align = clip2(alignment);
7075 if (allocation.align < 4096) {
7076 allocation.align = 4096;
7077 }
7078 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
7079 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7080 allocation.align, allocation.size);
7081 return false;
7082 }
7083 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007084}
David Ng38e2d232013-03-15 20:05:58 -07007085#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007086#ifdef USE_ION
7087int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007088 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7089 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007090{
Arun Menon906de572013-06-18 17:01:40 -07007091 int fd = -EINVAL;
7092 int rc = -EINVAL;
7093 int ion_dev_flag;
7094 struct vdec_ion ion_buf_info;
7095 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7096 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7097 return -EINVAL;
7098 }
7099 ion_dev_flag = O_RDONLY;
7100 fd = open (MEM_DEVICE, ion_dev_flag);
7101 if (fd < 0) {
7102 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7103 return fd;
7104 }
7105 alloc_data->flags = 0;
7106 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7107 alloc_data->flags |= ION_FLAG_CACHED;
7108 }
7109 alloc_data->len = buffer_size;
7110 alloc_data->align = clip2(alignment);
7111 if (alloc_data->align < 4096) {
7112 alloc_data->align = 4096;
7113 }
7114 if ((secure_mode) && (flag & ION_SECURE))
7115 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007116
Arun Menon906de572013-06-18 17:01:40 -07007117 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7118 if (secure_mode)
7119 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7120 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7121 if (rc || !alloc_data->handle) {
7122 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7123 alloc_data->handle = NULL;
7124 close(fd);
7125 fd = -ENOMEM;
7126 return fd;
7127 }
7128 fd_data->handle = alloc_data->handle;
7129 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7130 if (rc) {
7131 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7132 ion_buf_info.ion_alloc_data = *alloc_data;
7133 ion_buf_info.ion_device_fd = fd;
7134 ion_buf_info.fd_ion_data = *fd_data;
7135 free_ion_memory(&ion_buf_info);
7136 fd_data->fd =-1;
7137 close(fd);
7138 fd = -ENOMEM;
7139 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007140
Arun Menon906de572013-06-18 17:01:40 -07007141 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007142}
7143
Arun Menon906de572013-06-18 17:01:40 -07007144void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7145{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007146
Arun Menon906de572013-06-18 17:01:40 -07007147 if (!buf_ion_info) {
7148 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7149 return;
7150 }
7151 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7152 &buf_ion_info->ion_alloc_data.handle)) {
7153 DEBUG_PRINT_ERROR("\n ION: free failed" );
7154 }
7155 close(buf_ion_info->ion_device_fd);
7156 buf_ion_info->ion_device_fd = -1;
7157 buf_ion_info->ion_alloc_data.handle = NULL;
7158 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007159}
7160#endif
7161void omx_vdec::free_output_buffer_header()
7162{
Arun Menon906de572013-06-18 17:01:40 -07007163 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7164 output_use_buffer = false;
7165 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007166
Arun Menon906de572013-06-18 17:01:40 -07007167 if (m_out_mem_ptr) {
7168 free (m_out_mem_ptr);
7169 m_out_mem_ptr = NULL;
7170 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007171
Arun Menon906de572013-06-18 17:01:40 -07007172 if (m_platform_list) {
7173 free(m_platform_list);
7174 m_platform_list = NULL;
7175 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007176
Arun Menon906de572013-06-18 17:01:40 -07007177 if (drv_ctx.ptr_respbuffer) {
7178 free (drv_ctx.ptr_respbuffer);
7179 drv_ctx.ptr_respbuffer = NULL;
7180 }
7181 if (drv_ctx.ptr_outputbuffer) {
7182 free (drv_ctx.ptr_outputbuffer);
7183 drv_ctx.ptr_outputbuffer = NULL;
7184 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007185#ifdef USE_ION
7186 if (drv_ctx.op_buf_ion_info) {
7187 DEBUG_PRINT_LOW("\n Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007188 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007189 drv_ctx.op_buf_ion_info = NULL;
7190 }
7191#endif
7192}
7193
7194void omx_vdec::free_input_buffer_header()
7195{
7196 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007197 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007198 if (m_inp_heap_ptr) {
7199 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7200 free (m_inp_heap_ptr);
7201 m_inp_heap_ptr = NULL;
7202 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007203
Arun Menon906de572013-06-18 17:01:40 -07007204 if (m_phdr_pmem_ptr) {
7205 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7206 free (m_phdr_pmem_ptr);
7207 m_phdr_pmem_ptr = NULL;
7208 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007209 }
Arun Menon906de572013-06-18 17:01:40 -07007210 if (m_inp_mem_ptr) {
7211 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7212 free (m_inp_mem_ptr);
7213 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007214 }
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007215 /* We just freed all the buffer headers, every thing in m_input_free_q
7216 * is now invalid */
7217 while (m_input_free_q.m_size) {
7218 unsigned address, p2, id;
7219 m_input_free_q.pop_entry(&address, &p2, &id);
7220 }
Arun Menon906de572013-06-18 17:01:40 -07007221 if (drv_ctx.ptr_inputbuffer) {
7222 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7223 free (drv_ctx.ptr_inputbuffer);
7224 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007225 }
7226#ifdef USE_ION
7227 if (drv_ctx.ip_buf_ion_info) {
7228 DEBUG_PRINT_LOW("\n Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007229 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007230 drv_ctx.ip_buf_ion_info = NULL;
7231 }
7232#endif
7233}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007234
7235int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007236{
Arun Menon906de572013-06-18 17:01:40 -07007237 enum v4l2_buf_type btype;
7238 int rc = 0;
7239 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007240
Arun Menon906de572013-06-18 17:01:40 -07007241 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7242 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7243 v4l2_port = OUTPUT_PORT;
7244 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7245 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7246 v4l2_port = CAPTURE_PORT;
7247 } else if (port == OMX_ALL) {
7248 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7249 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007250
Arun Menon906de572013-06-18 17:01:40 -07007251 if (!rc_input)
7252 return rc_input;
7253 else
7254 return rc_output;
7255 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007256
Arun Menon906de572013-06-18 17:01:40 -07007257 if (!streaming[v4l2_port]) {
7258 // already streamed off, warn and move on
7259 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7260 " which is already streamed off", v4l2_port);
7261 return 0;
7262 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007263
Arun Menon906de572013-06-18 17:01:40 -07007264 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007265
Arun Menon906de572013-06-18 17:01:40 -07007266 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7267 if (rc) {
7268 /*TODO: How to handle this case */
7269 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
7270 } else {
7271 streaming[v4l2_port] = false;
7272 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007273
Arun Menon906de572013-06-18 17:01:40 -07007274 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007275}
7276
7277OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7278{
Arun Menon906de572013-06-18 17:01:40 -07007279 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7280 struct v4l2_requestbuffers bufreq;
7281 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7282 struct v4l2_format fmt;
7283 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007284 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007285 buffer_prop->actualcount, buffer_prop->buffer_size);
7286 bufreq.memory = V4L2_MEMORY_USERPTR;
7287 bufreq.count = 1;
7288 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7289 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7290 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7291 fmt.fmt.pix_mp.pixelformat = output_capability;
7292 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7293 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7294 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7295 fmt.fmt.pix_mp.pixelformat = capture_capability;
7296 } else {
7297 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007298 }
Arun Menon906de572013-06-18 17:01:40 -07007299 if (eRet==OMX_ErrorNone) {
7300 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007301 }
Arun Menon906de572013-06-18 17:01:40 -07007302 if (ret) {
7303 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7304 /*TODO: How to handle this case */
7305 eRet = OMX_ErrorInsufficientResources;
7306 return eRet;
7307 } else {
7308 buffer_prop->actualcount = bufreq.count;
7309 buffer_prop->mincount = bufreq.count;
7310 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007311 }
Arun Menon906de572013-06-18 17:01:40 -07007312 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7313 buffer_prop->actualcount, buffer_prop->buffer_size);
7314
7315 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7316 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7317
7318 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7319
7320 update_resolution(fmt.fmt.pix_mp.width,
7321 fmt.fmt.pix_mp.height,
7322 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7323 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7324 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7325 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
7326 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
7327
7328 if (ret) {
7329 /*TODO: How to handle this case */
7330 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7331 eRet = OMX_ErrorInsufficientResources;
7332 } else {
7333 int extra_idx = 0;
7334
7335 eRet = is_video_session_supported();
7336 if (eRet)
7337 return eRet;
7338
7339 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7340 buf_size = buffer_prop->buffer_size;
7341 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7342 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7343 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7344 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7345 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7346 return OMX_ErrorBadParameter;
7347 }
7348 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7349 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7350 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7351 }
7352 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7353 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7354 }
7355 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7356 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7357 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7358 client_extra_data_size);
7359 }
7360 if (client_extra_data_size) {
7361 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7362 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7363 }
7364 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7365 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7366 drv_ctx.extradata_info.buffer_size = extra_data_size;
7367 buf_size += client_extra_data_size;
7368 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7369 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7370 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7371 if (in_reconfig) // BufReq will be set to driver when port is disabled
7372 buffer_prop->buffer_size = buf_size;
7373 else if (buf_size != buffer_prop->buffer_size) {
7374 buffer_prop->buffer_size = buf_size;
7375 eRet = set_buffer_req(buffer_prop);
7376 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007377 }
Arun Menon906de572013-06-18 17:01:40 -07007378 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7379 buffer_prop->actualcount, buffer_prop->buffer_size);
7380 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007381}
7382
7383OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7384{
Arun Menon906de572013-06-18 17:01:40 -07007385 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7386 unsigned buf_size = 0;
7387 struct v4l2_format fmt;
7388 struct v4l2_requestbuffers bufreq;
7389 int ret;
7390 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7391 buffer_prop->actualcount, buffer_prop->buffer_size);
7392 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7393 if (buf_size != buffer_prop->buffer_size) {
7394 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7395 buffer_prop->buffer_size, buf_size);
7396 eRet = OMX_ErrorBadParameter;
7397 } else {
7398 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7399 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007400
Arun Menon906de572013-06-18 17:01:40 -07007401 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7402 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7403 fmt.fmt.pix_mp.pixelformat = output_capability;
7404 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7405 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7406 fmt.fmt.pix_mp.pixelformat = capture_capability;
7407 } else {
7408 eRet = OMX_ErrorBadParameter;
7409 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007410
Arun Menon906de572013-06-18 17:01:40 -07007411 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7412 if (ret) {
7413 /*TODO: How to handle this case */
7414 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7415 eRet = OMX_ErrorInsufficientResources;
7416 }
7417
7418 bufreq.memory = V4L2_MEMORY_USERPTR;
7419 bufreq.count = buffer_prop->actualcount;
7420 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7421 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7422 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7423 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7424 } else {
7425 eRet = OMX_ErrorBadParameter;
7426 }
7427
7428 if (eRet==OMX_ErrorNone) {
7429 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7430 }
7431
7432 if (ret) {
7433 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7434 /*TODO: How to handle this case */
7435 eRet = OMX_ErrorInsufficientResources;
7436 } else if (bufreq.count < buffer_prop->actualcount) {
7437 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7438 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7439 buffer_prop->actualcount, bufreq.count);
7440 eRet = OMX_ErrorInsufficientResources;
7441 } else {
7442 if (!client_buffers.update_buffer_req()) {
7443 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7444 eRet = OMX_ErrorInsufficientResources;
7445 }
7446 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007447 }
Arun Menon906de572013-06-18 17:01:40 -07007448 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007449}
7450
Shalaj Jain273b3e02012-06-22 19:08:03 -07007451OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7452{
Arun Menon906de572013-06-18 17:01:40 -07007453 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7454 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007455}
7456
7457OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7458{
Arun Menon906de572013-06-18 17:01:40 -07007459 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7460 if (!portDefn) {
7461 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007462 }
Arun Menon906de572013-06-18 17:01:40 -07007463 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
7464 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7465 portDefn->nSize = sizeof(portDefn);
7466 portDefn->eDomain = OMX_PortDomainVideo;
7467 if (drv_ctx.frame_rate.fps_denominator > 0)
7468 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7469 drv_ctx.frame_rate.fps_denominator;
7470 else {
7471 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7472 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007473 }
Arun Menon906de572013-06-18 17:01:40 -07007474 if (0 == portDefn->nPortIndex) {
7475 portDefn->eDir = OMX_DirInput;
7476 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7477 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7478 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7479 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7480 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7481 portDefn->bEnabled = m_inp_bEnabled;
7482 portDefn->bPopulated = m_inp_bPopulated;
7483 } else if (1 == portDefn->nPortIndex) {
7484 unsigned int buf_size = 0;
7485 if (!client_buffers.update_buffer_req()) {
7486 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
7487 return OMX_ErrorHardware;
7488 }
7489 if (!client_buffers.get_buffer_req(buf_size)) {
7490 DEBUG_PRINT_ERROR("\n update buffer requirements");
7491 return OMX_ErrorHardware;
7492 }
7493 portDefn->nBufferSize = buf_size;
7494 portDefn->eDir = OMX_DirOutput;
7495 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7496 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7497 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7498 portDefn->bEnabled = m_out_bEnabled;
7499 portDefn->bPopulated = m_out_bPopulated;
7500 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
7501 DEBUG_PRINT_ERROR("\n Error in getting color format");
7502 return OMX_ErrorHardware;
7503 }
7504 } else {
7505 portDefn->eDir = OMX_DirMax;
7506 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7507 (int)portDefn->nPortIndex);
7508 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007509 }
Arun Menon906de572013-06-18 17:01:40 -07007510 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7511 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7512 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7513 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7514 DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
7515 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
7516 portDefn->format.video.nFrameHeight,
7517 portDefn->format.video.nStride,
7518 portDefn->format.video.nSliceHeight);
7519 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007520
7521}
7522
7523OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7524{
Arun Menon906de572013-06-18 17:01:40 -07007525 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7526 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7527 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007528
Arun Menon906de572013-06-18 17:01:40 -07007529 if (!m_out_mem_ptr) {
7530 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
7531 int nBufHdrSize = 0;
7532 int nPlatformEntrySize = 0;
7533 int nPlatformListSize = 0;
7534 int nPMEMInfoSize = 0;
7535 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7536 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7537 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007538
Arun Menon906de572013-06-18 17:01:40 -07007539 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
7540 drv_ctx.op_buf.actualcount);
7541 nBufHdrSize = drv_ctx.op_buf.actualcount *
7542 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007543
Arun Menon906de572013-06-18 17:01:40 -07007544 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7545 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7546 nPlatformListSize = drv_ctx.op_buf.actualcount *
7547 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7548 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7549 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007550
Arun Menon906de572013-06-18 17:01:40 -07007551 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
7552 sizeof(OMX_BUFFERHEADERTYPE),
7553 nPMEMInfoSize,
7554 nPlatformListSize);
7555 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
7556 m_out_bm_count);
7557 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7558 // Alloc mem for platform specific info
7559 char *pPtr=NULL;
7560 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7561 nPMEMInfoSize,1);
7562 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7563 calloc (sizeof(struct vdec_bufferpayload),
7564 drv_ctx.op_buf.actualcount);
7565 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7566 calloc (sizeof (struct vdec_output_frameinfo),
7567 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007568#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007569 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7570 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007571#endif
7572
Arun Menon906de572013-06-18 17:01:40 -07007573 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7574 && drv_ctx.ptr_respbuffer) {
7575 bufHdr = m_out_mem_ptr;
7576 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7577 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7578 (((char *) m_platform_list) + nPlatformListSize);
7579 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7580 (((char *) m_platform_entry) + nPlatformEntrySize);
7581 pPlatformList = m_platform_list;
7582 pPlatformEntry = m_platform_entry;
7583 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007584
Arun Menon906de572013-06-18 17:01:40 -07007585 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007586
Arun Menon906de572013-06-18 17:01:40 -07007587 // Settting the entire storage nicely
7588 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
7589 m_out_mem_ptr,pPlatformEntry);
7590 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
7591 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7592 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7593 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7594 // Set the values when we determine the right HxW param
7595 bufHdr->nAllocLen = 0;
7596 bufHdr->nFilledLen = 0;
7597 bufHdr->pAppPrivate = NULL;
7598 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7599 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7600 pPlatformEntry->entry = pPMEMInfo;
7601 // Initialize the Platform List
7602 pPlatformList->nEntries = 1;
7603 pPlatformList->entryList = pPlatformEntry;
7604 // Keep pBuffer NULL till vdec is opened
7605 bufHdr->pBuffer = NULL;
7606 pPMEMInfo->offset = 0;
7607 pPMEMInfo->pmem_fd = 0;
7608 bufHdr->pPlatformPrivate = pPlatformList;
7609 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007610#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007611 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007612#endif
Arun Menon906de572013-06-18 17:01:40 -07007613 /*Create a mapping between buffers*/
7614 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7615 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7616 &drv_ctx.ptr_outputbuffer[i];
7617 // Move the buffer and buffer header pointers
7618 bufHdr++;
7619 pPMEMInfo++;
7620 pPlatformEntry++;
7621 pPlatformList++;
7622 }
7623 } else {
7624 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
7625 m_out_mem_ptr, pPtr);
7626 if (m_out_mem_ptr) {
7627 free(m_out_mem_ptr);
7628 m_out_mem_ptr = NULL;
7629 }
7630 if (pPtr) {
7631 free(pPtr);
7632 pPtr = NULL;
7633 }
7634 if (drv_ctx.ptr_outputbuffer) {
7635 free(drv_ctx.ptr_outputbuffer);
7636 drv_ctx.ptr_outputbuffer = NULL;
7637 }
7638 if (drv_ctx.ptr_respbuffer) {
7639 free(drv_ctx.ptr_respbuffer);
7640 drv_ctx.ptr_respbuffer = NULL;
7641 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007642#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007643 if (drv_ctx.op_buf_ion_info) {
7644 DEBUG_PRINT_LOW("\n Free o/p ion context");
7645 free(drv_ctx.op_buf_ion_info);
7646 drv_ctx.op_buf_ion_info = NULL;
7647 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007648#endif
Arun Menon906de572013-06-18 17:01:40 -07007649 eRet = OMX_ErrorInsufficientResources;
7650 }
7651 } else {
7652 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007653 }
Arun Menon906de572013-06-18 17:01:40 -07007654 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007655}
7656
7657void omx_vdec::complete_pending_buffer_done_cbs()
7658{
Arun Menon906de572013-06-18 17:01:40 -07007659 unsigned p1;
7660 unsigned p2;
7661 unsigned ident;
7662 omx_cmd_queue tmp_q, pending_bd_q;
7663 pthread_mutex_lock(&m_lock);
7664 // pop all pending GENERATE FDB from ftb queue
7665 while (m_ftb_q.m_size) {
7666 m_ftb_q.pop_entry(&p1,&p2,&ident);
7667 if (ident == OMX_COMPONENT_GENERATE_FBD) {
7668 pending_bd_q.insert_entry(p1,p2,ident);
7669 } else {
7670 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007671 }
Arun Menon906de572013-06-18 17:01:40 -07007672 }
7673 //return all non GENERATE FDB to ftb queue
7674 while (tmp_q.m_size) {
7675 tmp_q.pop_entry(&p1,&p2,&ident);
7676 m_ftb_q.insert_entry(p1,p2,ident);
7677 }
7678 // pop all pending GENERATE EDB from etb queue
7679 while (m_etb_q.m_size) {
7680 m_etb_q.pop_entry(&p1,&p2,&ident);
7681 if (ident == OMX_COMPONENT_GENERATE_EBD) {
7682 pending_bd_q.insert_entry(p1,p2,ident);
7683 } else {
7684 tmp_q.insert_entry(p1,p2,ident);
7685 }
7686 }
7687 //return all non GENERATE FDB to etb queue
7688 while (tmp_q.m_size) {
7689 tmp_q.pop_entry(&p1,&p2,&ident);
7690 m_etb_q.insert_entry(p1,p2,ident);
7691 }
7692 pthread_mutex_unlock(&m_lock);
7693 // process all pending buffer dones
7694 while (pending_bd_q.m_size) {
7695 pending_bd_q.pop_entry(&p1,&p2,&ident);
7696 switch (ident) {
7697 case OMX_COMPONENT_GENERATE_EBD:
7698 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
7699 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
7700 omx_report_error ();
7701 }
7702 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007703
Arun Menon906de572013-06-18 17:01:40 -07007704 case OMX_COMPONENT_GENERATE_FBD:
7705 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
7706 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
7707 omx_report_error ();
7708 }
7709 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007710 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007711 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007712}
7713
7714void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
7715{
Arun Menon906de572013-06-18 17:01:40 -07007716 OMX_U32 new_frame_interval = 0;
7717 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
7718 && llabs(act_timestamp - prev_ts) > 2000) {
7719 new_frame_interval = client_set_fps ? frm_int :
7720 llabs(act_timestamp - prev_ts);
7721 if (new_frame_interval < frm_int || frm_int == 0) {
7722 frm_int = new_frame_interval;
7723 if (frm_int) {
7724 drv_ctx.frame_rate.fps_numerator = 1e6;
7725 drv_ctx.frame_rate.fps_denominator = frm_int;
7726 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
7727 frm_int, drv_ctx.frame_rate.fps_numerator /
7728 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007729
Arun Menon906de572013-06-18 17:01:40 -07007730 /* We need to report the difference between this FBD and the previous FBD
7731 * back to the driver for clock scaling purposes. */
7732 struct v4l2_outputparm oparm;
7733 /*XXX: we're providing timing info as seconds per frame rather than frames
7734 * per second.*/
7735 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
7736 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007737
Arun Menon906de572013-06-18 17:01:40 -07007738 struct v4l2_streamparm sparm;
7739 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7740 sparm.parm.output = oparm;
7741 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
7742 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
7743 performance might be affected");
7744 }
7745
7746 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007747 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007748 }
Arun Menon906de572013-06-18 17:01:40 -07007749 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007750}
7751
7752void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
7753{
Arun Menon906de572013-06-18 17:01:40 -07007754 if (rst_prev_ts && VALID_TS(act_timestamp)) {
7755 prev_ts = act_timestamp;
7756 rst_prev_ts = false;
7757 } else if (VALID_TS(prev_ts)) {
7758 bool codec_cond = (drv_ctx.timestamp_adjust)?
7759 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
7760 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
7761 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
7762 if (frm_int > 0 && codec_cond) {
7763 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
7764 act_timestamp = prev_ts + frm_int;
7765 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
7766 prev_ts = act_timestamp;
7767 } else
7768 set_frame_rate(act_timestamp);
7769 } else if (frm_int > 0) // In this case the frame rate was set along
7770 { // with the port definition, start ts with 0
7771 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
7772 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007773 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007774}
7775
7776void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
7777{
Arun Menon906de572013-06-18 17:01:40 -07007778 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
7779 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05307780 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07007781 OMX_U32 frame_rate = 0;
7782 int consumed_len = 0;
7783 OMX_U32 num_MB_in_frame;
7784 OMX_U32 recovery_sei_flags = 1;
7785 int enable = 0;
7786 OMX_U32 mbaff = 0;
7787 int buf_index = p_buf_hdr - m_out_mem_ptr;
7788 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
7789 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
7790 p_buf_hdr->nOffset;
7791 if (!drv_ctx.extradata_info.uaddr) {
7792 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007793 }
Arun Menon906de572013-06-18 17:01:40 -07007794 p_extra = (OMX_OTHER_EXTRADATATYPE *)
7795 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
7796 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
7797 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
7798 p_extra = NULL;
7799 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
7800 if (data) {
7801 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
7802 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
7803 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
7804 DEBUG_PRINT_LOW("Invalid extra data size");
7805 break;
7806 }
7807 switch ((unsigned long)data->eType) {
7808 case EXTRADATA_INTERLACE_VIDEO:
7809 struct msm_vidc_interlace_payload *payload;
7810 payload = (struct msm_vidc_interlace_payload *)data->data;
7811 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
7812 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
7813 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
7814 else {
7815 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
7816 enable = 1;
7817 }
7818 if (m_enable_android_native_buffers)
7819 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
7820 PP_PARAM_INTERLACED, (void*)&enable);
7821 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
7822 append_interlace_extradata(p_extra, payload->format);
7823 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
7824 }
7825 break;
7826 case EXTRADATA_FRAME_RATE:
7827 struct msm_vidc_framerate_payload *frame_rate_payload;
7828 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
7829 frame_rate = frame_rate_payload->frame_rate;
7830 break;
7831 case EXTRADATA_TIMESTAMP:
7832 struct msm_vidc_ts_payload *time_stamp_payload;
7833 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05307834 time_stamp = time_stamp_payload->timestamp_lo;
7835 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
7836 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07007837 break;
7838 case EXTRADATA_NUM_CONCEALED_MB:
7839 struct msm_vidc_concealmb_payload *conceal_mb_payload;
7840 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
7841 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
7842 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
7843 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
7844 break;
7845 case EXTRADATA_INDEX:
7846 int *etype;
7847 etype = (int *)(data->data);
7848 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
7849 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
7850 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
7851 if (aspect_ratio_payload) {
7852 ((struct vdec_output_frameinfo *)
7853 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
7854 ((struct vdec_output_frameinfo *)
7855 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
7856 }
7857 }
7858 break;
7859 case EXTRADATA_RECOVERY_POINT_SEI:
7860 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
7861 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
7862 recovery_sei_flags = recovery_sei_payload->flags;
7863 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
7864 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7865 DEBUG_PRINT_HIGH("\n");
7866 DEBUG_PRINT_HIGH("***************************************************\n");
7867 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
7868 DEBUG_PRINT_HIGH("***************************************************\n");
7869 }
7870 break;
7871 case EXTRADATA_PANSCAN_WINDOW:
7872 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
7873 break;
7874 case EXTRADATA_MPEG2_SEQDISP:
7875 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
7876 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
7877 if (seqdisp_payload) {
7878 m_disp_hor_size = seqdisp_payload->disp_width;
7879 m_disp_vert_size = seqdisp_payload->disp_height;
7880 }
7881 break;
7882 default:
7883 goto unrecognized_extradata;
7884 }
7885 consumed_len += data->nSize;
7886 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
7887 }
7888 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
7889 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
7890 append_frame_info_extradata(p_extra,
7891 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05307892 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07007893 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
7894 }
7895 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007896unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07007897 if (!secure_mode && client_extradata)
7898 append_terminator_extradata(p_extra);
7899 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007900}
7901
Vinay Kalia9c00cae2012-12-06 16:08:20 -08007902OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07007903 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007904{
Arun Menon906de572013-06-18 17:01:40 -07007905 OMX_ERRORTYPE ret = OMX_ErrorNone;
7906 struct v4l2_control control;
7907 if (m_state != OMX_StateLoaded) {
7908 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
7909 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08007910 }
Arun Menon906de572013-06-18 17:01:40 -07007911 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
7912 client_extradata, requested_extradata, enable, is_internal);
7913
7914 if (!is_internal) {
7915 if (enable)
7916 client_extradata |= requested_extradata;
7917 else
7918 client_extradata = client_extradata & ~requested_extradata;
7919 }
7920
7921 if (enable) {
7922 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
7923 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7924 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
7925 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7926 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
7927 " Quality of interlaced clips might be impacted.\n");
7928 }
7929 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
7930 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7931 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
7932 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7933 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
7934 }
7935 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7936 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
7937 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7938 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
7939 }
7940 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7941 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
7942 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7943 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
7944 }
7945 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7946 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
7947 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7948 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7949 }
7950 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7951 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
7952 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7953 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7954 }
7955 if (output_capability == V4L2_PIX_FMT_MPEG2) {
7956 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7957 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
7958 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7959 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7960 }
7961 }
7962 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
7963 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7964 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
7965 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7966 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
7967 }
7968 }
7969 }
7970 ret = get_buffer_req(&drv_ctx.op_buf);
7971 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007972}
7973
7974OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
7975{
Arun Menon906de572013-06-18 17:01:40 -07007976 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
7977 OMX_U8 *data_ptr = extra->data, data = 0;
7978 while (byte_count < extra->nDataSize) {
7979 data = *data_ptr;
7980 while (data) {
7981 num_MB += (data&0x01);
7982 data >>= 1;
7983 }
7984 data_ptr++;
7985 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007986 }
Arun Menon906de572013-06-18 17:01:40 -07007987 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
7988 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
7989 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007990}
7991
7992void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
7993{
Arun Menon906de572013-06-18 17:01:40 -07007994 if (!m_debug_extradata)
7995 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007996
7997 DEBUG_PRINT_HIGH(
Arun Menon906de572013-06-18 17:01:40 -07007998 "============== Extra Data ==============\n"
7999 " Size: %lu \n"
8000 " Version: %lu \n"
8001 " PortIndex: %lu \n"
8002 " Type: %x \n"
8003 " DataSize: %lu \n",
8004 extra->nSize, extra->nVersion.nVersion,
8005 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008006
Arun Menon906de572013-06-18 17:01:40 -07008007 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8008 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8009 DEBUG_PRINT_HIGH(
8010 "------ Interlace Format ------\n"
8011 " Size: %lu \n"
8012 " Version: %lu \n"
8013 " PortIndex: %lu \n"
8014 " Is Interlace Format: %d \n"
8015 " Interlace Formats: %lu \n"
8016 "=========== End of Interlace ===========\n",
8017 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8018 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8019 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8020 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8021
8022 DEBUG_PRINT_HIGH(
8023 "-------- Frame Format --------\n"
8024 " Picture Type: %d \n"
8025 " Interlace Type: %d \n"
8026 " Pan Scan Total Frame Num: %lu \n"
8027 " Concealed Macro Blocks: %lu \n"
8028 " frame rate: %lu \n"
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308029 " Time Stamp: %lu \n"
Arun Menon906de572013-06-18 17:01:40 -07008030 " Aspect Ratio X: %lu \n"
8031 " Aspect Ratio Y: %lu \n",
8032 fminfo->ePicType,
8033 fminfo->interlaceType,
8034 fminfo->panScan.numWindows,
8035 fminfo->nConcealedMacroblocks,
8036 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308037 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008038 fminfo->aspectRatio.aspectRatioX,
8039 fminfo->aspectRatio.aspectRatioY);
8040
8041 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8042 DEBUG_PRINT_HIGH(
8043 "------------------------------\n"
8044 " Pan Scan Frame Num: %lu \n"
8045 " Rectangle x: %ld \n"
8046 " Rectangle y: %ld \n"
8047 " Rectangle dx: %ld \n"
8048 " Rectangle dy: %ld \n",
8049 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8050 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8051 }
8052
8053 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8054 } else if (extra->eType == OMX_ExtraDataNone) {
8055 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8056 } else {
8057 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008058 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008059}
8060
8061void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008062 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008063{
Arun Menon906de572013-06-18 17:01:40 -07008064 OMX_STREAMINTERLACEFORMAT *interlace_format;
8065 OMX_U32 mbaff = 0;
8066 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8067 return;
8068 }
8069 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8070 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8071 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8072 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8073 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8074 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8075 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8076 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8077 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8078 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8079 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8080 interlace_format->bInterlaceFormat = OMX_FALSE;
8081 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8082 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8083 } else {
8084 interlace_format->bInterlaceFormat = OMX_TRUE;
8085 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8086 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8087 }
8088 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008089}
8090
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008091void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008092 struct vdec_aspectratioinfo *aspect_ratio_info,
8093 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008094{
Arun Menon906de572013-06-18 17:01:40 -07008095 m_extradata = frame_info;
8096 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8097 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308098 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008099 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008100}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008101
8102void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008103 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308104 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008105 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008106{
Arun Menon906de572013-06-18 17:01:40 -07008107 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8108 struct msm_vidc_panscan_window *panscan_window;
8109 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008110 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008111 }
Arun Menon906de572013-06-18 17:01:40 -07008112 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8113 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8114 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8115 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8116 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8117 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8118 switch (picture_type) {
8119 case PICTURE_TYPE_I:
8120 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8121 break;
8122 case PICTURE_TYPE_P:
8123 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8124 break;
8125 case PICTURE_TYPE_B:
8126 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8127 break;
8128 default:
8129 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8130 }
8131 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8132 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8133 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8134 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8135 else
8136 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8137 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8138 frame_info->nConcealedMacroblocks = num_conceal_mb;
8139 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308140 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008141 frame_info->panScan.numWindows = 0;
8142 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8143 if (m_disp_hor_size && m_disp_vert_size) {
8144 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8145 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8146 }
8147 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008148
Arun Menon906de572013-06-18 17:01:40 -07008149 if (panscan_payload) {
8150 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8151 panscan_window = &panscan_payload->wnd[0];
8152 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8153 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8154 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8155 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8156 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8157 panscan_window++;
8158 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008159 }
Arun Menon906de572013-06-18 17:01:40 -07008160 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8161 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008162}
8163
8164void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8165{
Arun Menon906de572013-06-18 17:01:40 -07008166 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8167 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8168 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8169 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8170 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8171 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8172 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8173 *portDefn = m_port_def;
8174 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8175 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
8176 portDefn->format.video.nFrameWidth,
8177 portDefn->format.video.nStride,
8178 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008179}
8180
8181void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8182{
Arun Menon906de572013-06-18 17:01:40 -07008183 if (!client_extradata) {
8184 return;
8185 }
8186 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8187 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8188 extra->eType = OMX_ExtraDataNone;
8189 extra->nDataSize = 0;
8190 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008191
Arun Menon906de572013-06-18 17:01:40 -07008192 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008193}
8194
8195OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8196{
Arun Menon906de572013-06-18 17:01:40 -07008197 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8198 if (index >= drv_ctx.ip_buf.actualcount) {
8199 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8200 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008201 }
Arun Menon906de572013-06-18 17:01:40 -07008202 if (m_desc_buffer_ptr == NULL) {
8203 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8204 calloc( (sizeof(desc_buffer_hdr)),
8205 drv_ctx.ip_buf.actualcount);
8206 if (m_desc_buffer_ptr == NULL) {
8207 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8208 return OMX_ErrorInsufficientResources;
8209 }
8210 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008211
Arun Menon906de572013-06-18 17:01:40 -07008212 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8213 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
8214 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8215 return OMX_ErrorInsufficientResources;
8216 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008217
Arun Menon906de572013-06-18 17:01:40 -07008218 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008219}
8220
8221void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8222{
Arun Menon906de572013-06-18 17:01:40 -07008223 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8224 if (m_demux_entries < 8192) {
8225 m_demux_offsets[m_demux_entries++] = address_offset;
8226 }
8227 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008228}
8229
8230void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8231{
Arun Menon906de572013-06-18 17:01:40 -07008232 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8233 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8234 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008235
Arun Menon906de572013-06-18 17:01:40 -07008236 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008237
Arun Menon906de572013-06-18 17:01:40 -07008238 while (index < bytes_to_parse) {
8239 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8240 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8241 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8242 (buf[index+2] == 0x01)) ) {
8243 //Found start code, insert address offset
8244 insert_demux_addr_offset(index);
8245 if (buf[index+2] == 0x01) // 3 byte start code
8246 index += 3;
8247 else //4 byte start code
8248 index += 4;
8249 } else
8250 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008251 }
Arun Menon906de572013-06-18 17:01:40 -07008252 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8253 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008254}
8255
8256OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8257{
Arun Menon906de572013-06-18 17:01:40 -07008258 //fix this, handle 3 byte start code, vc1 terminator entry
8259 OMX_U8 *p_demux_data = NULL;
8260 OMX_U32 desc_data = 0;
8261 OMX_U32 start_addr = 0;
8262 OMX_U32 nal_size = 0;
8263 OMX_U32 suffix_byte = 0;
8264 OMX_U32 demux_index = 0;
8265 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008266
Arun Menon906de572013-06-18 17:01:40 -07008267 if (m_desc_buffer_ptr == NULL) {
8268 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8269 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008270 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008271
Arun Menon906de572013-06-18 17:01:40 -07008272 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8273 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8274 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8275 return OMX_ErrorBadParameter;
8276 }
8277
8278 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8279
8280 if ( ((OMX_U8*)p_demux_data == NULL) ||
8281 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8282 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8283 return OMX_ErrorBadParameter;
8284 } else {
8285 for (; demux_index < m_demux_entries; demux_index++) {
8286 desc_data = 0;
8287 start_addr = m_demux_offsets[demux_index];
8288 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8289 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8290 } else {
8291 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8292 }
8293 if (demux_index < (m_demux_entries - 1)) {
8294 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8295 } else {
8296 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8297 }
8298 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8299 (void *)start_addr,
8300 suffix_byte,
8301 nal_size,
8302 demux_index);
8303 desc_data = (start_addr >> 3) << 1;
8304 desc_data |= (start_addr & 7) << 21;
8305 desc_data |= suffix_byte << 24;
8306
8307 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8308 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8309 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8310 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8311
8312 p_demux_data += 16;
8313 }
8314 if (codec_type_parse == CODEC_TYPE_VC1) {
8315 DEBUG_PRINT_LOW("VC1 terminator entry");
8316 desc_data = 0;
8317 desc_data = 0x82 << 24;
8318 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8319 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8320 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8321 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8322 p_demux_data += 16;
8323 m_demux_entries++;
8324 }
8325 //Add zero word to indicate end of descriptors
8326 memset(p_demux_data, 0, sizeof(OMX_U32));
8327
8328 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8329 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8330 }
8331 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8332 m_demux_entries = 0;
8333 DEBUG_PRINT_LOW("Demux table complete!");
8334 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008335}
8336
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008337OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008338{
Arun Menon906de572013-06-18 17:01:40 -07008339 OMX_ERRORTYPE err = OMX_ErrorNone;
8340 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8341 if (iDivXDrmDecrypt) {
8342 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8343 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008344 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008345 delete iDivXDrmDecrypt;
8346 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008347 }
8348 } else {
8349 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
8350 err = OMX_ErrorUndefined;
8351 }
8352 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008353}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008354
Vinay Kaliada4f4422013-01-09 10:45:03 -08008355omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8356{
Arun Menon906de572013-06-18 17:01:40 -07008357 enabled = false;
8358 omx = NULL;
8359 init_members();
8360 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008361}
8362
8363void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8364{
Arun Menon906de572013-06-18 17:01:40 -07008365 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008366}
8367
Arun Menon906de572013-06-18 17:01:40 -07008368void omx_vdec::allocate_color_convert_buf::init_members()
8369{
8370 allocated_count = 0;
8371 buffer_size_req = 0;
8372 buffer_alignment_req = 0;
8373 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8374 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8375 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8376 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008377#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008378 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008379#endif
Arun Menon906de572013-06-18 17:01:40 -07008380 for (int i = 0; i < MAX_COUNT; i++)
8381 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008382}
8383
Arun Menon906de572013-06-18 17:01:40 -07008384omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8385{
8386 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008387}
8388
8389bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8390{
Arun Menon906de572013-06-18 17:01:40 -07008391 bool status = true;
8392 unsigned int src_size = 0, destination_size = 0;
8393 OMX_COLOR_FORMATTYPE drv_color_format;
8394 if (!omx) {
8395 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8396 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008397 }
Arun Menon906de572013-06-18 17:01:40 -07008398 if (!enabled) {
8399 DEBUG_PRINT_HIGH("\n No color conversion required");
8400 return status;
8401 }
8402 pthread_mutex_lock(&omx->c_lock);
8403 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8404 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8405 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
8406 status = false;
8407 goto fail_update_buf_req;
8408 }
8409 c2d.close();
8410 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8411 omx->drv_ctx.video_resolution.frame_width,
8412 NV12_128m,YCbCr420P);
8413 if (status) {
8414 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8415 if (status)
8416 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8417 }
8418 if (status) {
8419 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8420 !destination_size) {
8421 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
8422 "driver size %d destination size %d",
8423 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8424 status = false;
8425 c2d.close();
8426 buffer_size_req = 0;
8427 } else {
8428 buffer_size_req = destination_size;
8429 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8430 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8431 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8432 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8433 }
8434 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008435fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008436 pthread_mutex_unlock(&omx->c_lock);
8437 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008438}
8439
8440bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008441 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008442{
Arun Menon906de572013-06-18 17:01:40 -07008443 bool status = true;
8444 OMX_COLOR_FORMATTYPE drv_color_format;
8445 if (!omx) {
8446 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8447 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008448 }
Arun Menon906de572013-06-18 17:01:40 -07008449 pthread_mutex_lock(&omx->c_lock);
8450 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8451 drv_color_format = (OMX_COLOR_FORMATTYPE)
8452 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8453 else {
8454 DEBUG_PRINT_ERROR("\n Incorrect color format");
8455 status = false;
8456 }
8457 if (status && (drv_color_format != dest_color_format)) {
8458 DEBUG_PRINT_LOW("Enabling C2D\n");
8459 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
8460 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
8461 status = false;
8462 } else {
8463 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8464 if (enabled)
8465 c2d.destroy();
8466 enabled = false;
8467 if (!c2d.init()) {
8468 DEBUG_PRINT_ERROR("\n open failed for c2d");
8469 status = false;
8470 } else
8471 enabled = true;
8472 }
8473 } else {
8474 if (enabled)
8475 c2d.destroy();
8476 enabled = false;
8477 }
8478 pthread_mutex_unlock(&omx->c_lock);
8479 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008480}
8481
8482OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8483{
Arun Menon906de572013-06-18 17:01:40 -07008484 if (!omx) {
8485 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8486 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008487 }
Arun Menon906de572013-06-18 17:01:40 -07008488 if (!enabled)
8489 return omx->m_out_mem_ptr;
8490 return m_out_mem_ptr_client;
8491}
8492
8493 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
8494(OMX_BUFFERHEADERTYPE *bufadd)
8495{
8496 if (!omx) {
8497 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8498 return NULL;
8499 }
8500 if (!enabled)
8501 return bufadd;
8502
8503 unsigned index = 0;
8504 index = bufadd - omx->m_out_mem_ptr;
8505 if (index < omx->drv_ctx.op_buf.actualcount) {
8506 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
8507 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
8508 bool status;
8509 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
8510 pthread_mutex_lock(&omx->c_lock);
8511 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
8512 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
8513 pmem_baseaddress[index], pmem_baseaddress[index]);
8514 pthread_mutex_unlock(&omx->c_lock);
8515 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
8516 if (!status) {
8517 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
8518 m_out_mem_ptr_client[index].nFilledLen = 0;
8519 return &m_out_mem_ptr_client[index];
8520 }
8521 } else
8522 m_out_mem_ptr_client[index].nFilledLen = 0;
8523 return &m_out_mem_ptr_client[index];
8524 }
8525 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
8526 return NULL;
8527}
8528
8529 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
8530(OMX_BUFFERHEADERTYPE *bufadd)
8531{
8532 if (!omx) {
8533 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8534 return NULL;
8535 }
8536 if (!enabled)
8537 return bufadd;
8538 unsigned index = 0;
8539 index = bufadd - m_out_mem_ptr_client;
8540 if (index < omx->drv_ctx.op_buf.actualcount) {
8541 return &omx->m_out_mem_ptr[index];
8542 }
8543 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
8544 return NULL;
8545}
8546 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
8547(unsigned int &buffer_size)
8548{
8549 bool status = true;
8550 pthread_mutex_lock(&omx->c_lock);
8551 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008552 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07008553 else {
8554 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
8555 DEBUG_PRINT_ERROR("\n Get buffer size failed");
8556 status = false;
8557 goto fail_get_buffer_size;
8558 }
8559 }
8560 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
8561 buffer_size = omx->drv_ctx.op_buf.buffer_size;
8562 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8563 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008564fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07008565 pthread_mutex_unlock(&omx->c_lock);
8566 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008567}
8568OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07008569 OMX_BUFFERHEADERTYPE *bufhdr)
8570{
8571 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008572
Arun Menon906de572013-06-18 17:01:40 -07008573 if (!enabled)
8574 return omx->free_output_buffer(bufhdr);
8575 if (enabled && omx->is_component_secure())
8576 return OMX_ErrorNone;
8577 if (!allocated_count || !bufhdr) {
8578 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
8579 return OMX_ErrorBadParameter;
8580 }
8581 index = bufhdr - m_out_mem_ptr_client;
8582 if (index >= omx->drv_ctx.op_buf.actualcount) {
8583 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
8584 return OMX_ErrorBadParameter;
8585 }
8586 if (pmem_fd[index] > 0) {
8587 munmap(pmem_baseaddress[index], buffer_size_req);
8588 close(pmem_fd[index]);
8589 }
8590 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008591#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008592 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008593#endif
Arun Menon906de572013-06-18 17:01:40 -07008594 m_heap_ptr[index].video_heap_ptr = NULL;
8595 if (allocated_count > 0)
8596 allocated_count--;
8597 else
8598 allocated_count = 0;
8599 if (!allocated_count) {
8600 pthread_mutex_lock(&omx->c_lock);
8601 c2d.close();
8602 init_members();
8603 pthread_mutex_unlock(&omx->c_lock);
8604 }
8605 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008606}
8607
8608OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07008609 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008610{
Arun Menon906de572013-06-18 17:01:40 -07008611 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8612 if (!enabled) {
8613 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
8614 return eRet;
8615 }
8616 if (enabled && omx->is_component_secure()) {
8617 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
8618 omx->is_component_secure());
8619 return OMX_ErrorUnsupportedSetting;
8620 }
8621 if (!bufferHdr || bytes > buffer_size_req) {
8622 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
8623 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
8624 buffer_size_req,bytes);
8625 return OMX_ErrorBadParameter;
8626 }
8627 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
8628 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
8629 return OMX_ErrorInsufficientResources;
8630 }
8631 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
8632 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
8633 port,appData,omx->drv_ctx.op_buf.buffer_size);
8634 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
8635 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
8636 return eRet;
8637 }
8638 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
8639 omx->drv_ctx.op_buf.actualcount) {
8640 DEBUG_PRINT_ERROR("\n Invalid header index %d",
8641 (temp_bufferHdr - omx->m_out_mem_ptr));
8642 return OMX_ErrorUndefined;
8643 }
8644 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008645#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008646 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
8647 buffer_size_req,buffer_alignment_req,
8648 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
8649 0);
8650 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
8651 if (op_buf_ion_info[i].ion_device_fd < 0) {
8652 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
8653 return OMX_ErrorInsufficientResources;
8654 }
8655 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
8656 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008657
Arun Menon906de572013-06-18 17:01:40 -07008658 if (pmem_baseaddress[i] == MAP_FAILED) {
8659 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
8660 close(pmem_fd[i]);
8661 omx->free_ion_memory(&op_buf_ion_info[i]);
8662 return OMX_ErrorInsufficientResources;
8663 }
8664 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
8665 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
8666 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008667#endif
Arun Menon906de572013-06-18 17:01:40 -07008668 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
8669 m_pmem_info_client[i].offset = 0;
8670 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
8671 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8672 m_platform_list_client[i].nEntries = 1;
8673 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
8674 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
8675 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
8676 m_out_mem_ptr_client[i].nFilledLen = 0;
8677 m_out_mem_ptr_client[i].nFlags = 0;
8678 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8679 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
8680 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
8681 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
8682 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
8683 m_out_mem_ptr_client[i].pAppPrivate = appData;
8684 *bufferHdr = &m_out_mem_ptr_client[i];
8685 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
8686 allocated_count++;
8687 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008688}
8689
8690bool omx_vdec::is_component_secure()
8691{
Arun Menon906de572013-06-18 17:01:40 -07008692 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008693}
8694
8695bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
8696{
Arun Menon906de572013-06-18 17:01:40 -07008697 bool status = true;
8698 if (!enabled) {
8699 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8700 dest_color_format = (OMX_COLOR_FORMATTYPE)
8701 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8702 else
8703 status = false;
8704 } else {
8705 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8706 status = false;
8707 } else
8708 dest_color_format = OMX_COLOR_FormatYUV420Planar;
8709 }
8710 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008711}