blob: 1cc9e019906e88fbb128e79e591a2762d88b1422 [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
64#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
65#include <gralloc_priv.h>
66#endif
67
68#if defined (_ANDROID_ICS_)
69#include <genlock.h>
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070070#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070071#endif
72
73#ifdef _ANDROID_
74#include "DivXDrmDecrypt.h"
75#endif //_ANDROID_
76
77#ifdef USE_EGL_IMAGE_GPU
78#include <EGL/egl.h>
79#include <EGL/eglQCOM.h>
80#define EGL_BUFFER_HANDLE_QCOM 0x4F00
81#define EGL_BUFFER_OFFSET_QCOM 0x4F01
82#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -070083#ifdef INPUT_BUFFER_LOG
84#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0"
85#define INPUT_BUFFER_FILE_NAME_LEN 30
86FILE *inputBufferFile1;
87char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
88#endif
89#ifdef OUTPUT_BUFFER_LOG
90FILE *outputBufferFile1;
91char outputfilename [] = "/data/output.yuv";
Vinay Kalia21649b32013-03-18 17:28:07 -070092
Shalaj Jain273b3e02012-06-22 19:08:03 -070093#endif
94#ifdef OUTPUT_EXTRADATA_LOG
95FILE *outputExtradataFile;
96char ouputextradatafilename [] = "/data/extradata";
97#endif
98
99#define DEFAULT_FPS 30
100#define MAX_INPUT_ERROR DEFAULT_FPS
101#define MAX_SUPPORTED_FPS 120
102
103#define VC1_SP_MP_START_CODE 0xC5000000
104#define VC1_SP_MP_START_CODE_MASK 0xFF000000
105#define VC1_AP_SEQ_START_CODE 0x0F010000
106#define VC1_STRUCT_C_PROFILE_MASK 0xF0
107#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
108#define VC1_SIMPLE_PROFILE 0
109#define VC1_MAIN_PROFILE 1
110#define VC1_ADVANCE_PROFILE 3
111#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
112#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
113#define VC1_STRUCT_C_LEN 4
114#define VC1_STRUCT_C_POS 8
115#define VC1_STRUCT_A_POS 12
116#define VC1_STRUCT_B_POS 24
117#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700118#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700119
120#define MEM_DEVICE "/dev/ion"
121#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
122
123#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700124extern "C" {
125#include<utils/Log.h>
126}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700127#endif//_ANDROID_
128
Vinay Kalia53fa6832012-10-11 17:55:30 -0700129#define SZ_4K 0x1000
130#define SZ_1M 0x100000
131
Shalaj Jain273b3e02012-06-22 19:08:03 -0700132#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
133#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 -0700134#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
135
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800136#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700137void* async_message_thread (void *input)
138{
Arun Menon906de572013-06-18 17:01:40 -0700139 OMX_BUFFERHEADERTYPE *buffer;
140 struct v4l2_plane plane[VIDEO_MAX_PLANES];
141 struct pollfd pfd;
142 struct v4l2_buffer v4l2_buf;
143 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
144 struct v4l2_event dqevent;
145 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
146 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
147 pfd.fd = omx->drv_ctx.video_driver_fd;
148 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
149 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
150 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
151 while (1) {
152 rc = poll(&pfd, 1, POLL_TIMEOUT);
153 if (!rc) {
154 DEBUG_PRINT_ERROR("Poll timedout\n");
155 break;
156 } else if (rc < 0) {
157 DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
158 break;
159 }
160 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
161 struct vdec_msginfo vdec_msg;
162 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
163 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
164 v4l2_buf.length = omx->drv_ctx.num_planes;
165 v4l2_buf.m.planes = plane;
166 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
167 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
168 vdec_msg.status_code=VDEC_S_SUCCESS;
169 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
170 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
171 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
172 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
173 (uint64_t)v4l2_buf.timestamp.tv_usec;
174 if (vdec_msg.msgdata.output_frame.len) {
175 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
176 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
177 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
178 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
179 }
180 if (omx->async_message_process(input,&vdec_msg) < 0) {
181 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
182 break;
183 }
184 }
185 }
186 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
187 struct vdec_msginfo vdec_msg;
188 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
189 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
190 v4l2_buf.length = 1;
191 v4l2_buf.m.planes = plane;
192 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
193 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
194 vdec_msg.status_code=VDEC_S_SUCCESS;
195 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
196 if (omx->async_message_process(input,&vdec_msg) < 0) {
197 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
198 break;
199 }
200 }
201 }
202 if (pfd.revents & POLLPRI) {
203 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
204 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
205 struct vdec_msginfo vdec_msg;
206 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
207 vdec_msg.status_code=VDEC_S_SUCCESS;
208 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved insufficient\n");
209 if (omx->async_message_process(input,&vdec_msg) < 0) {
210 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
211 break;
212 }
213 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
214 struct vdec_msginfo vdec_msg;
215 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
216 vdec_msg.status_code=VDEC_S_SUCCESS;
217 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved \n");
218 if (omx->async_message_process(input,&vdec_msg) < 0) {
219 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
220 break;
221 }
222 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
223 vdec_msg.status_code=VDEC_S_SUCCESS;
224 DEBUG_PRINT_HIGH("VIDC Output Flush Done 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 if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
230 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
231 break;
232 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
233 struct vdec_msginfo vdec_msg;
234 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
235 vdec_msg.status_code=VDEC_S_SUCCESS;
236 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
237 if (omx->async_message_process(input,&vdec_msg) < 0) {
238 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
239 break;
240 }
241 } else {
242 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
243 continue;
244 }
245 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700246 }
Arun Menon906de572013-06-18 17:01:40 -0700247 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
248 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700249}
250
251void* message_thread(void *input)
252{
Arun Menon906de572013-06-18 17:01:40 -0700253 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
254 unsigned char id;
255 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700256
Arun Menon906de572013-06-18 17:01:40 -0700257 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
258 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
259 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700260
Arun Menon906de572013-06-18 17:01:40 -0700261 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700262
Arun Menon906de572013-06-18 17:01:40 -0700263 if (0 == n) {
264 break;
265 }
266
267 if (1 == n) {
268 omx->process_event_cb(omx, id);
269 }
270 if ((n < 0) && (errno != EINTR)) {
271 DEBUG_PRINT_LOW("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
272 break;
273 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700274 }
Arun Menon906de572013-06-18 17:01:40 -0700275 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
276 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700277}
278
279void post_message(omx_vdec *omx, unsigned char id)
280{
Arun Menon906de572013-06-18 17:01:40 -0700281 int ret_value;
282 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
283 ret_value = write(omx->m_pipe_out, &id, 1);
284 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700285}
286
287// omx_cmd_queue destructor
288omx_vdec::omx_cmd_queue::~omx_cmd_queue()
289{
Arun Menon906de572013-06-18 17:01:40 -0700290 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700291}
292
293// omx cmd queue constructor
294omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
295{
296 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
297}
298
299// omx cmd queue insert
300bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
301{
Arun Menon906de572013-06-18 17:01:40 -0700302 bool ret = true;
303 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
304 m_q[m_write].id = id;
305 m_q[m_write].param1 = p1;
306 m_q[m_write].param2 = p2;
307 m_write++;
308 m_size ++;
309 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
310 m_write = 0;
311 }
312 } else {
313 ret = false;
314 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700315 }
Arun Menon906de572013-06-18 17:01:40 -0700316 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700317}
318
319// omx cmd queue pop
320bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
321{
Arun Menon906de572013-06-18 17:01:40 -0700322 bool ret = true;
323 if (m_size > 0) {
324 *id = m_q[m_read].id;
325 *p1 = m_q[m_read].param1;
326 *p2 = m_q[m_read].param2;
327 // Move the read pointer ahead
328 ++m_read;
329 --m_size;
330 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
331 m_read = 0;
332 }
333 } else {
334 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700335 }
Arun Menon906de572013-06-18 17:01:40 -0700336 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700337}
338
339// Retrieve the first mesg type in the queue
340unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
341{
342 return m_q[m_read].id;
343}
344
345#ifdef _ANDROID_
346omx_vdec::ts_arr_list::ts_arr_list()
347{
Arun Menon906de572013-06-18 17:01:40 -0700348 //initialize timestamps array
349 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700350}
351omx_vdec::ts_arr_list::~ts_arr_list()
352{
Arun Menon906de572013-06-18 17:01:40 -0700353 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700354}
355
356bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
357{
Arun Menon906de572013-06-18 17:01:40 -0700358 bool ret = true;
359 bool duplicate_ts = false;
360 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700361
Arun Menon906de572013-06-18 17:01:40 -0700362 //insert at the first available empty location
363 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
364 if (!m_ts_arr_list[idx].valid) {
365 //found invalid or empty entry, save timestamp
366 m_ts_arr_list[idx].valid = true;
367 m_ts_arr_list[idx].timestamp = ts;
368 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
369 ts, idx);
370 break;
371 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700372 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700373
Arun Menon906de572013-06-18 17:01:40 -0700374 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
375 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
376 ret = false;
377 }
378 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700379}
380
381bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
382{
Arun Menon906de572013-06-18 17:01:40 -0700383 bool ret = true;
384 int min_idx = -1;
385 OMX_TICKS min_ts = 0;
386 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700387
Arun Menon906de572013-06-18 17:01:40 -0700388 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700389
Arun Menon906de572013-06-18 17:01:40 -0700390 if (m_ts_arr_list[idx].valid) {
391 //found valid entry, save index
392 if (min_idx < 0) {
393 //first valid entry
394 min_ts = m_ts_arr_list[idx].timestamp;
395 min_idx = idx;
396 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
397 min_ts = m_ts_arr_list[idx].timestamp;
398 min_idx = idx;
399 }
400 }
401
Shalaj Jain273b3e02012-06-22 19:08:03 -0700402 }
403
Arun Menon906de572013-06-18 17:01:40 -0700404 if (min_idx < 0) {
405 //no valid entries found
406 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
407 ts = 0;
408 ret = false;
409 } else {
410 ts = m_ts_arr_list[min_idx].timestamp;
411 m_ts_arr_list[min_idx].valid = false;
412 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
413 ts, min_idx);
414 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700415
Arun Menon906de572013-06-18 17:01:40 -0700416 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700417
418}
419
420
421bool omx_vdec::ts_arr_list::reset_ts_list()
422{
Arun Menon906de572013-06-18 17:01:40 -0700423 bool ret = true;
424 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700425
Arun Menon906de572013-06-18 17:01:40 -0700426 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
427 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
428 m_ts_arr_list[idx].valid = false;
429 }
430 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700431}
432#endif
433
434// factory function executed by the core to create instances
435void *get_omx_component_factory_fn(void)
436{
Arun Menon906de572013-06-18 17:01:40 -0700437 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700438}
439
440#ifdef _ANDROID_
441#ifdef USE_ION
442VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700443 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700444{
Arun Menon906de572013-06-18 17:01:40 -0700445 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700446}
447#else
448VideoHeap::VideoHeap(int fd, size_t size, void* base)
449{
450 // dup file descriptor, map once, use pmem
451 init(dup(fd), base, size, 0 , MEM_DEVICE);
452}
453#endif
454#endif // _ANDROID_
455/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700456 FUNCTION
457 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700458
Arun Menon906de572013-06-18 17:01:40 -0700459 DESCRIPTION
460 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700461
Arun Menon906de572013-06-18 17:01:40 -0700462 PARAMETERS
463 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700464
Arun Menon906de572013-06-18 17:01:40 -0700465 RETURN VALUE
466 None.
467 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800468omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700469 m_state(OMX_StateInvalid),
470 m_app_data(NULL),
471 m_inp_mem_ptr(NULL),
472 m_out_mem_ptr(NULL),
473 m_inp_err_count(0),
474 input_flush_progress (false),
475 output_flush_progress (false),
476 input_use_buffer (false),
477 output_use_buffer (false),
478 ouput_egl_buffers(false),
479 m_use_output_pmem(OMX_FALSE),
480 m_out_mem_region_smi(OMX_FALSE),
481 m_out_pvt_entry_pmem(OMX_FALSE),
482 pending_input_buffers(0),
483 pending_output_buffers(0),
484 m_out_bm_count(0),
485 m_inp_bm_count(0),
486 m_inp_bPopulated(OMX_FALSE),
487 m_out_bPopulated(OMX_FALSE),
488 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700489#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700490 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700491#endif
Arun Menon906de572013-06-18 17:01:40 -0700492 m_inp_bEnabled(OMX_TRUE),
493 m_out_bEnabled(OMX_TRUE),
494 m_in_alloc_cnt(0),
495 m_platform_list(NULL),
496 m_platform_entry(NULL),
497 m_pmem_info(NULL),
498 arbitrary_bytes (true),
499 psource_frame (NULL),
500 pdest_frame (NULL),
501 m_inp_heap_ptr (NULL),
502 m_phdr_pmem_ptr(NULL),
503 m_heap_inp_bm_count (0),
504 codec_type_parse ((codec_type)0),
505 first_frame_meta (true),
506 frame_count (0),
507 nal_count (0),
508 nal_length(0),
509 look_ahead_nal (false),
510 first_frame(0),
511 first_buffer(NULL),
512 first_frame_size (0),
513 m_device_file_ptr(NULL),
514 m_vc1_profile((vc1_profile_type)0),
515 m_profile(0),
516 h264_last_au_ts(LLONG_MAX),
517 h264_last_au_flags(0),
518 prev_ts(LLONG_MAX),
519 rst_prev_ts(true),
520 frm_int(0),
521 m_disp_hor_size(0),
522 m_disp_vert_size(0),
523 in_reconfig(false),
524 m_display_id(NULL),
525 h264_parser(NULL),
526 client_extradata(0),
527 m_reject_avc_1080p_mp (0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700528#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700529 m_enable_android_native_buffers(OMX_FALSE),
530 m_use_android_native_buffers(OMX_FALSE),
531 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700532#endif
Arun Menon906de572013-06-18 17:01:40 -0700533 m_desc_buffer_ptr(NULL),
534 secure_mode(false),
535 client_set_fps(false)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700536{
Arun Menon906de572013-06-18 17:01:40 -0700537 /* Assumption is that , to begin with , we have all the frames with decoder */
538 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700539#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700540 char property_value[PROPERTY_VALUE_MAX] = {0};
541 property_get("vidc.dec.debug.perf", property_value, "0");
542 perf_flag = atoi(property_value);
543 if (perf_flag) {
544 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
545 dec_time.start();
546 proc_frms = latency = 0;
547 }
548 prev_n_filled_len = 0;
549 property_value[0] = '\0';
550 property_get("vidc.dec.debug.ts", property_value, "0");
551 m_debug_timestamp = atoi(property_value);
552 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
553 if (m_debug_timestamp) {
554 time_stamp_dts.set_timestamp_reorder_mode(true);
555 time_stamp_dts.enable_debug_print(true);
556 }
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.debug.concealedmb", property_value, "0");
560 m_debug_concealedmb = atoi(property_value);
561 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700562
Arun Menon906de572013-06-18 17:01:40 -0700563 property_value[0] = '\0';
564 property_get("vidc.dec.profile.check", property_value, "0");
565 m_reject_avc_1080p_mp = atoi(property_value);
566 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530567
Shalaj Jain273b3e02012-06-22 19:08:03 -0700568#endif
Arun Menon906de572013-06-18 17:01:40 -0700569 memset(&m_cmp,0,sizeof(m_cmp));
570 memset(&m_cb,0,sizeof(m_cb));
571 memset (&drv_ctx,0,sizeof(drv_ctx));
572 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
573 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
574 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
575 m_demux_entries = 0;
576 msg_thread_id = 0;
577 async_thread_id = 0;
578 msg_thread_created = false;
579 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700580#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700581 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700582#endif
Arun Menon906de572013-06-18 17:01:40 -0700583 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
584 drv_ctx.timestamp_adjust = false;
585 drv_ctx.video_driver_fd = -1;
586 m_vendor_config.pData = NULL;
587 pthread_mutex_init(&m_lock, NULL);
588 pthread_mutex_init(&c_lock, NULL);
589 sem_init(&m_cmd_lock,0,0);
590 streaming[CAPTURE_PORT] =
591 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700592#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700593 char extradata_value[PROPERTY_VALUE_MAX] = {0};
594 property_get("vidc.dec.debug.extradata", extradata_value, "0");
595 m_debug_extradata = atoi(extradata_value);
596 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700597#endif
Arun Menon906de572013-06-18 17:01:40 -0700598 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
599 client_buffers.set_vdec_client(this);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700600}
601
Vinay Kalia85793762012-06-14 19:12:34 -0700602static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700603 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
604 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
605 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
606 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
607 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700608};
609
610static OMX_ERRORTYPE subscribe_to_events(int fd)
611{
Arun Menon906de572013-06-18 17:01:40 -0700612 OMX_ERRORTYPE eRet = OMX_ErrorNone;
613 struct v4l2_event_subscription sub;
614 int array_sz = sizeof(event_type)/sizeof(int);
615 int i,rc;
616 if (fd < 0) {
617 printf("Invalid input: %d\n", fd);
618 return OMX_ErrorBadParameter;
619 }
Vinay Kalia85793762012-06-14 19:12:34 -0700620
Arun Menon906de572013-06-18 17:01:40 -0700621 for (i = 0; i < array_sz; ++i) {
622 memset(&sub, 0, sizeof(sub));
623 sub.type = event_type[i];
624 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
625 if (rc) {
626 printf("Failed to subscribe event: 0x%x\n", sub.type);
627 break;
628 }
629 }
630 if (i < array_sz) {
631 for (--i; i >=0 ; i--) {
632 memset(&sub, 0, sizeof(sub));
633 sub.type = event_type[i];
634 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
635 if (rc)
636 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
637 }
638 eRet = OMX_ErrorNotImplemented;
639 }
640 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700641}
642
643
644static OMX_ERRORTYPE unsubscribe_to_events(int fd)
645{
Arun Menon906de572013-06-18 17:01:40 -0700646 OMX_ERRORTYPE eRet = OMX_ErrorNone;
647 struct v4l2_event_subscription sub;
648 int array_sz = sizeof(event_type)/sizeof(int);
649 int i,rc;
650 if (fd < 0) {
651 printf("Invalid input: %d\n", fd);
652 return OMX_ErrorBadParameter;
653 }
Vinay Kalia85793762012-06-14 19:12:34 -0700654
Arun Menon906de572013-06-18 17:01:40 -0700655 for (i = 0; i < array_sz; ++i) {
656 memset(&sub, 0, sizeof(sub));
657 sub.type = event_type[i];
658 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
659 if (rc) {
660 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
661 break;
662 }
663 }
664 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700665}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700666
667/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700668 FUNCTION
669 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700670
Arun Menon906de572013-06-18 17:01:40 -0700671 DESCRIPTION
672 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700673
Arun Menon906de572013-06-18 17:01:40 -0700674 PARAMETERS
675 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700676
Arun Menon906de572013-06-18 17:01:40 -0700677 RETURN VALUE
678 None.
679 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700680omx_vdec::~omx_vdec()
681{
Arun Menon906de572013-06-18 17:01:40 -0700682 m_pmem_info = NULL;
683 struct v4l2_decoder_cmd dec;
684 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
685 if (m_pipe_in) close(m_pipe_in);
686 if (m_pipe_out) close(m_pipe_out);
687 m_pipe_in = -1;
688 m_pipe_out = -1;
689 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
690 if (msg_thread_created)
691 pthread_join(msg_thread_id,NULL);
692 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
693 dec.cmd = V4L2_DEC_CMD_STOP;
694 if (drv_ctx.video_driver_fd >=0 ) {
695 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
696 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
697 }
698 if (async_thread_created)
699 pthread_join(async_thread_id,NULL);
700 unsubscribe_to_events(drv_ctx.video_driver_fd);
701 close(drv_ctx.video_driver_fd);
702 pthread_mutex_destroy(&m_lock);
703 pthread_mutex_destroy(&c_lock);
704 sem_destroy(&m_cmd_lock);
705 if (perf_flag) {
706 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
707 dec_time.end();
708 }
709 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700710}
711
Arun Menon906de572013-06-18 17:01:40 -0700712int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
713{
714 struct v4l2_requestbuffers bufreq;
715 int rc = 0;
716 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
717 bufreq.memory = V4L2_MEMORY_USERPTR;
718 bufreq.count = 0;
719 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
720 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
721 }
722 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700723}
724
Shalaj Jain273b3e02012-06-22 19:08:03 -0700725/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700726 FUNCTION
727 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700728
Arun Menon906de572013-06-18 17:01:40 -0700729 DESCRIPTION
730 IL Client callbacks are generated through this routine. The decoder
731 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700732
Arun Menon906de572013-06-18 17:01:40 -0700733 PARAMETERS
734 ctxt -- Context information related to the self.
735 id -- Event identifier. This could be any of the following:
736 1. Command completion event
737 2. Buffer done callback event
738 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700739
Arun Menon906de572013-06-18 17:01:40 -0700740 RETURN VALUE
741 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700742
Arun Menon906de572013-06-18 17:01:40 -0700743 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700744void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
745{
Arun Menon906de572013-06-18 17:01:40 -0700746 signed p1; // Parameter - 1
747 signed p2; // Parameter - 2
748 unsigned ident;
749 unsigned qsize=0; // qsize
750 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700751
Arun Menon906de572013-06-18 17:01:40 -0700752 if (!pThis) {
753 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
754 __func__);
755 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700756 }
757
Arun Menon906de572013-06-18 17:01:40 -0700758 // Protect the shared queue data structure
759 do {
760 /*Read the message id's from the queue*/
761 pthread_mutex_lock(&pThis->m_lock);
762 qsize = pThis->m_cmd_q.m_size;
763 if (qsize) {
764 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700765 }
Arun Menon906de572013-06-18 17:01:40 -0700766
767 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
768 qsize = pThis->m_ftb_q.m_size;
769 if (qsize) {
770 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
771 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700772 }
Arun Menon906de572013-06-18 17:01:40 -0700773
774 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
775 qsize = pThis->m_etb_q.m_size;
776 if (qsize) {
777 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
778 }
779 }
780 pthread_mutex_unlock(&pThis->m_lock);
781
782 /*process message if we have one*/
783 if (qsize > 0) {
784 id = ident;
785 switch (id) {
786 case OMX_COMPONENT_GENERATE_EVENT:
787 if (pThis->m_cb.EventHandler) {
788 switch (p1) {
789 case OMX_CommandStateSet:
790 pThis->m_state = (OMX_STATETYPE) p2;
791 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
792 pThis->m_state);
793 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
794 OMX_EventCmdComplete, p1, p2, NULL);
795 break;
796
797 case OMX_EventError:
798 if (p2 == OMX_StateInvalid) {
799 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
800 pThis->m_state = (OMX_STATETYPE) p2;
801 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
802 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
803 } else if (p2 == OMX_ErrorHardware) {
804 pThis->omx_report_error();
805 } else {
806 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
807 OMX_EventError, p2, (OMX_U32)NULL, NULL );
808 }
809 break;
810
811 case OMX_CommandPortDisable:
812 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
813 if (BITMASK_PRESENT(&pThis->m_flags,
814 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
815 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
816 break;
817 }
818 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
819 OMX_ERRORTYPE eRet = OMX_ErrorNone;
820 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
821 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
822 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
823 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
824 pThis->in_reconfig = false;
825 if (eRet != OMX_ErrorNone) {
826 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
827 pThis->omx_report_error();
828 break;
829 }
830 }
831 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
832 OMX_EventCmdComplete, p1, p2, NULL );
833 break;
834 case OMX_CommandPortEnable:
835 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
836 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
837 OMX_EventCmdComplete, p1, p2, NULL );
838 break;
839
840 default:
841 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
842 OMX_EventCmdComplete, p1, p2, NULL );
843 break;
844
845 }
846 } else {
847 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
848 }
849 break;
850 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
851 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
852 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
853 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
854 pThis->omx_report_error ();
855 }
856 break;
857 case OMX_COMPONENT_GENERATE_ETB:
858 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
859 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
860 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
861 pThis->omx_report_error ();
862 }
863 break;
864
865 case OMX_COMPONENT_GENERATE_FTB:
866 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
867 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
868 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
869 pThis->omx_report_error ();
870 }
871 break;
872
873 case OMX_COMPONENT_GENERATE_COMMAND:
874 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
875 (OMX_U32)p2,(OMX_PTR)NULL);
876 break;
877
878 case OMX_COMPONENT_GENERATE_EBD:
879
880 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
881 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
882 pThis->omx_report_error ();
883 } else {
884 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
885 pThis->m_inp_err_count++;
886 pThis->time_stamp_dts.remove_time_stamp(
887 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
888 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
889 ?true:false);
890 } else {
891 pThis->m_inp_err_count = 0;
892 }
893 if ( pThis->empty_buffer_done(&pThis->m_cmp,
894 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
895 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
896 pThis->omx_report_error ();
897 }
898 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
899 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
900 pThis->omx_report_error ();
901 }
902 }
903 break;
904 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
905 int64_t *timestamp = (int64_t *)p1;
906 if (p1) {
907 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
908 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
909 ?true:false);
910 free(timestamp);
911 }
912 }
913 break;
914 case OMX_COMPONENT_GENERATE_FBD:
915 if (p2 != VDEC_S_SUCCESS) {
916 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
917 pThis->omx_report_error ();
918 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
919 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
920 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
921 pThis->omx_report_error ();
922 }
923 break;
924
925 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
926 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
927 if (!pThis->input_flush_progress) {
928 DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
929 } else {
930 pThis->execute_input_flush();
931 if (pThis->m_cb.EventHandler) {
932 if (p2 != VDEC_S_SUCCESS) {
933 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
934 pThis->omx_report_error ();
935 } else {
936 /*Check if we need generate event for Flush done*/
937 if (BITMASK_PRESENT(&pThis->m_flags,
938 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
939 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
940 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
941 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
942 OMX_EventCmdComplete,OMX_CommandFlush,
943 OMX_CORE_INPUT_PORT_INDEX,NULL );
944 }
945 if (BITMASK_PRESENT(&pThis->m_flags,
946 OMX_COMPONENT_IDLE_PENDING)) {
947 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
948 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
949 pThis->omx_report_error ();
950 } else {
951 pThis->streaming[OUTPUT_PORT] = false;
952 }
953 if (!pThis->output_flush_progress) {
954 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
955 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
956 OMX_COMPONENT_GENERATE_STOP_DONE);
957 }
958 }
959 }
960 } else {
961 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
962 }
963 }
964 break;
965
966 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
967 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
968 if (!pThis->output_flush_progress) {
969 DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
970 } else {
971 pThis->execute_output_flush();
972 if (pThis->m_cb.EventHandler) {
973 if (p2 != VDEC_S_SUCCESS) {
974 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
975 pThis->omx_report_error ();
976 } else {
977 /*Check if we need generate event for Flush done*/
978 if (BITMASK_PRESENT(&pThis->m_flags,
979 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
980 DEBUG_PRINT_LOW("\n Notify Output Flush done");
981 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
982 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
983 OMX_EventCmdComplete,OMX_CommandFlush,
984 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
985 }
986 if (BITMASK_PRESENT(&pThis->m_flags,
987 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
988 DEBUG_PRINT_LOW("\n Internal flush complete");
989 BITMASK_CLEAR (&pThis->m_flags,
990 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
991 if (BITMASK_PRESENT(&pThis->m_flags,
992 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
993 pThis->post_event(OMX_CommandPortDisable,
994 OMX_CORE_OUTPUT_PORT_INDEX,
995 OMX_COMPONENT_GENERATE_EVENT);
996 BITMASK_CLEAR (&pThis->m_flags,
997 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
998
999 }
1000 }
1001
1002 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1003 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
1004 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1005 pThis->omx_report_error ();
1006 break;
1007 }
1008 pThis->streaming[CAPTURE_PORT] = false;
1009 if (!pThis->input_flush_progress) {
1010 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
1011 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1012 OMX_COMPONENT_GENERATE_STOP_DONE);
1013 }
1014 }
1015 }
1016 } else {
1017 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1018 }
1019 }
1020 break;
1021
1022 case OMX_COMPONENT_GENERATE_START_DONE:
1023 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1024
1025 if (pThis->m_cb.EventHandler) {
1026 if (p2 != VDEC_S_SUCCESS) {
1027 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1028 pThis->omx_report_error ();
1029 } else {
1030 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1031 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1032 DEBUG_PRINT_LOW("\n Move to executing");
1033 // Send the callback now
1034 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1035 pThis->m_state = OMX_StateExecuting;
1036 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1037 OMX_EventCmdComplete,OMX_CommandStateSet,
1038 OMX_StateExecuting, NULL);
1039 } else if (BITMASK_PRESENT(&pThis->m_flags,
1040 OMX_COMPONENT_PAUSE_PENDING)) {
1041 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1042 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
1043 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1044 pThis->omx_report_error ();
1045 }
1046 }
1047 }
1048 } else {
1049 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1050 }
1051 break;
1052
1053 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1054 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1055 if (pThis->m_cb.EventHandler) {
1056 if (p2 != VDEC_S_SUCCESS) {
1057 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1058 pThis->omx_report_error ();
1059 } else {
1060 pThis->complete_pending_buffer_done_cbs();
1061 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
1062 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1063 //Send the callback now
1064 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1065 pThis->m_state = OMX_StatePause;
1066 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1067 OMX_EventCmdComplete,OMX_CommandStateSet,
1068 OMX_StatePause, NULL);
1069 }
1070 }
1071 } else {
1072 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1073 }
1074
1075 break;
1076
1077 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1078 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1079 if (pThis->m_cb.EventHandler) {
1080 if (p2 != VDEC_S_SUCCESS) {
1081 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1082 pThis->omx_report_error ();
1083 } else {
1084 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1085 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1086 // Send the callback now
1087 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1088 pThis->m_state = OMX_StateExecuting;
1089 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1090 OMX_EventCmdComplete,OMX_CommandStateSet,
1091 OMX_StateExecuting,NULL);
1092 }
1093 }
1094 } else {
1095 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1096 }
1097
1098 break;
1099
1100 case OMX_COMPONENT_GENERATE_STOP_DONE:
1101 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1102 if (pThis->m_cb.EventHandler) {
1103 if (p2 != VDEC_S_SUCCESS) {
1104 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1105 pThis->omx_report_error ();
1106 } else {
1107 pThis->complete_pending_buffer_done_cbs();
1108 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
1109 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1110 // Send the callback now
1111 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1112 pThis->m_state = OMX_StateIdle;
1113 DEBUG_PRINT_LOW("\n Move to Idle State");
1114 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1115 OMX_EventCmdComplete,OMX_CommandStateSet,
1116 OMX_StateIdle,NULL);
1117 }
1118 }
1119 } else {
1120 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1121 }
1122
1123 break;
1124
1125 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1126 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
1127
1128 if (p2 == OMX_IndexParamPortDefinition) {
1129 pThis->in_reconfig = true;
1130 }
1131 if (pThis->m_cb.EventHandler) {
1132 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1133 OMX_EventPortSettingsChanged, p1, p2, NULL );
1134 } else {
1135 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1136 }
1137
1138 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) {
1139 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
1140 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
1141 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
1142 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
1143 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
1144 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
1145 else //unsupported interlace format; raise a error
1146 event = OMX_EventError;
1147 if (pThis->m_cb.EventHandler) {
1148 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1149 event, format, 0, NULL );
1150 } else {
1151 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1152 }
1153 }
1154 break;
1155
1156 case OMX_COMPONENT_GENERATE_EOS_DONE:
1157 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1158 if (pThis->m_cb.EventHandler) {
1159 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1160 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1161 } else {
1162 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1163 }
1164 pThis->prev_ts = LLONG_MAX;
1165 pThis->rst_prev_ts = true;
1166 break;
1167
1168 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1169 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1170 pThis->omx_report_error ();
1171 break;
1172
1173 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1174 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
1175 pThis->omx_report_unsupported_setting();
1176 break;
1177
1178 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG: {
1179 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
1180 if (pThis->m_cb.EventHandler) {
1181 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1182 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1183 } else {
1184 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1185 }
1186 }
1187 default:
1188 break;
1189 }
1190 }
1191 pthread_mutex_lock(&pThis->m_lock);
1192 qsize = pThis->m_cmd_q.m_size;
1193 if (pThis->m_state != OMX_StatePause)
1194 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1195 pthread_mutex_unlock(&pThis->m_lock);
1196 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001197
1198}
1199
Vinay Kaliab9e98102013-04-02 19:31:43 -07001200int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001201{
Arun Menon906de572013-06-18 17:01:40 -07001202 int format_changed = 0;
1203 if ((height != drv_ctx.video_resolution.frame_height) ||
1204 (width != drv_ctx.video_resolution.frame_width)) {
1205 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)\n",
1206 width, drv_ctx.video_resolution.frame_width,
1207 height,drv_ctx.video_resolution.frame_height);
1208 format_changed = 1;
1209 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001210 drv_ctx.video_resolution.frame_height = height;
1211 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001212 drv_ctx.video_resolution.scan_lines = scan_lines;
1213 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001214 rectangle.nLeft = 0;
1215 rectangle.nTop = 0;
1216 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1217 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Arun Menon906de572013-06-18 17:01:40 -07001218 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001219}
1220
Arun Menon6836ba02013-02-19 20:37:40 -08001221OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1222{
Arun Menon906de572013-06-18 17:01:40 -07001223 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1224 OMX_MAX_STRINGNAME_SIZE) &&
1225 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1226 m_decoder_capability.max_width = 1280;
1227 m_decoder_capability.max_height = 720;
1228 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1229 }
Arun Menon888aa852013-05-30 11:24:42 -07001230
Arun Menon906de572013-06-18 17:01:40 -07001231 if ((drv_ctx.video_resolution.frame_width *
1232 drv_ctx.video_resolution.frame_height >
1233 m_decoder_capability.max_width *
1234 m_decoder_capability.max_height) ||
1235 (drv_ctx.video_resolution.frame_width*
1236 drv_ctx.video_resolution.frame_height <
1237 m_decoder_capability.min_width *
1238 m_decoder_capability.min_height)) {
1239 DEBUG_PRINT_ERROR(
1240 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1241 drv_ctx.video_resolution.frame_width,
1242 drv_ctx.video_resolution.frame_height,
1243 m_decoder_capability.min_width,
1244 m_decoder_capability.min_height,
1245 m_decoder_capability.max_width,
1246 m_decoder_capability.max_height);
1247 return OMX_ErrorUnsupportedSetting;
1248 }
1249 DEBUG_PRINT_HIGH("\n video session supported\n");
1250 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001251}
1252
Shalaj Jain273b3e02012-06-22 19:08:03 -07001253/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001254 FUNCTION
1255 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001256
Arun Menon906de572013-06-18 17:01:40 -07001257 DESCRIPTION
1258 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001259
Arun Menon906de572013-06-18 17:01:40 -07001260 PARAMETERS
1261 ctxt -- Context information related to the self.
1262 id -- Event identifier. This could be any of the following:
1263 1. Command completion event
1264 2. Buffer done callback event
1265 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001266
Arun Menon906de572013-06-18 17:01:40 -07001267 RETURN VALUE
1268 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001269
Arun Menon906de572013-06-18 17:01:40 -07001270 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001271OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1272{
1273
Arun Menon906de572013-06-18 17:01:40 -07001274 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1275 struct v4l2_fmtdesc fdesc;
1276 struct v4l2_format fmt;
1277 struct v4l2_requestbuffers bufreq;
1278 struct v4l2_control control;
1279 struct v4l2_frmsizeenum frmsize;
1280 unsigned int alignment = 0,buffer_size = 0;
1281 int fds[2];
1282 int r,ret=0;
1283 bool codec_ambiguous = false;
1284 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Sachin Shahc82a18f2013-03-29 14:45:38 -07001285
1286#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07001287 char platform_name[64];
1288 property_get("ro.board.platform", platform_name, "0");
1289 if (!strncmp(platform_name, "msm8610", 7)) {
1290 device_name = (OMX_STRING)"/dev/video/q6_dec";
1291 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001292#endif
1293
Arun Menon906de572013-06-18 17:01:40 -07001294 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1295 struct v4l2_control control;
1296 secure_mode = true;
1297 arbitrary_bytes = false;
1298 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
1299 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001300
Arun Menon906de572013-06-18 17:01:40 -07001301 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001302
Arun Menon906de572013-06-18 17:01:40 -07001303 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d",
1304 drv_ctx.video_driver_fd, errno);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001305
Arun Menon906de572013-06-18 17:01:40 -07001306 if (drv_ctx.video_driver_fd == 0) {
1307 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again\n");
1308 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1309 close(0);
1310 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001311
Arun Menon906de572013-06-18 17:01:40 -07001312 if (drv_ctx.video_driver_fd < 0) {
1313 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1314 return OMX_ErrorInsufficientResources;
1315 }
1316 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1317 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001318
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001319 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001320 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001321 async_thread_created = true;
1322 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1323 }
1324 if (ret) {
1325 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1326 async_thread_created = false;
1327 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001328 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001329
1330#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001331 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001332#endif
1333#ifdef OUTPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001334 outputBufferFile1 = fopen (outputfilename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001335#endif
1336#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07001337 outputExtradataFile = fopen (ouputextradatafilename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001338#endif
1339
Arun Menon906de572013-06-18 17:01:40 -07001340 // Copy the role information which provides the decoder kind
1341 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001342
Arun Menon906de572013-06-18 17:01:40 -07001343 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1344 OMX_MAX_STRINGNAME_SIZE)) {
1345 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1346 OMX_MAX_STRINGNAME_SIZE);
1347 drv_ctx.timestamp_adjust = true;
1348 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1349 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1350 output_capability=V4L2_PIX_FMT_MPEG4;
1351 /*Initialize Start Code for MPEG4*/
1352 codec_type_parse = CODEC_TYPE_MPEG4;
1353 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001354#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001355 strcat(inputfilename, "m4v");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001356#endif
Arun Menon906de572013-06-18 17:01:40 -07001357 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1358 OMX_MAX_STRINGNAME_SIZE)) {
1359 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1360 OMX_MAX_STRINGNAME_SIZE);
1361 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1362 output_capability = V4L2_PIX_FMT_MPEG2;
1363 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1364 /*Initialize Start Code for MPEG2*/
1365 codec_type_parse = CODEC_TYPE_MPEG2;
1366 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001367#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001368 strcat(inputfilename, "mpg");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001369#endif
Arun Menon906de572013-06-18 17:01:40 -07001370 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1371 OMX_MAX_STRINGNAME_SIZE)) {
1372 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1373 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1374 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1375 eCompressionFormat = OMX_VIDEO_CodingH263;
1376 output_capability = V4L2_PIX_FMT_H263;
1377 codec_type_parse = CODEC_TYPE_H263;
1378 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001379#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001380 strcat(inputfilename, "263");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001381#endif
Arun Menon906de572013-06-18 17:01:40 -07001382 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1383 OMX_MAX_STRINGNAME_SIZE)) {
1384 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1385 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1386 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1387 output_capability = V4L2_PIX_FMT_DIVX_311;
1388 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1389 codec_type_parse = CODEC_TYPE_DIVX;
1390 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001391
Arun Menon906de572013-06-18 17:01:40 -07001392 eRet = createDivxDrmContext();
1393 if (eRet != OMX_ErrorNone) {
1394 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1395 return eRet;
1396 }
1397 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1398 OMX_MAX_STRINGNAME_SIZE)) {
1399 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1400 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1401 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1402 output_capability = V4L2_PIX_FMT_DIVX;
1403 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1404 codec_type_parse = CODEC_TYPE_DIVX;
1405 codec_ambiguous = true;
1406 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001407
Arun Menon906de572013-06-18 17:01:40 -07001408 eRet = createDivxDrmContext();
1409 if (eRet != OMX_ErrorNone) {
1410 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1411 return eRet;
1412 }
1413 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1414 OMX_MAX_STRINGNAME_SIZE)) {
1415 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1416 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1417 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1418 output_capability = V4L2_PIX_FMT_DIVX;
1419 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1420 codec_type_parse = CODEC_TYPE_DIVX;
1421 codec_ambiguous = true;
1422 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001423
Arun Menon906de572013-06-18 17:01:40 -07001424 eRet = createDivxDrmContext();
1425 if (eRet != OMX_ErrorNone) {
1426 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1427 return eRet;
1428 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001429
Arun Menon906de572013-06-18 17:01:40 -07001430 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1431 OMX_MAX_STRINGNAME_SIZE)) {
1432 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1433 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1434 output_capability=V4L2_PIX_FMT_H264;
1435 eCompressionFormat = OMX_VIDEO_CodingAVC;
1436 codec_type_parse = CODEC_TYPE_H264;
1437 m_frame_parser.init_start_codes (codec_type_parse);
1438 m_frame_parser.init_nal_length(nal_length);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001439#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001440 strcat(inputfilename, "264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001441#endif
Arun Menon906de572013-06-18 17:01:40 -07001442 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1443 OMX_MAX_STRINGNAME_SIZE)) {
1444 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1445 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1446 eCompressionFormat = OMX_VIDEO_CodingWMV;
1447 codec_type_parse = CODEC_TYPE_VC1;
1448 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1449 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001450#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001451 strcat(inputfilename, "vc1");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001452#endif
Arun Menon906de572013-06-18 17:01:40 -07001453 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1454 OMX_MAX_STRINGNAME_SIZE)) {
1455 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1456 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1457 eCompressionFormat = OMX_VIDEO_CodingWMV;
1458 codec_type_parse = CODEC_TYPE_VC1;
1459 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1460 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001461#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001462 strcat(inputfilename, "vc1");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001463#endif
Arun Menon906de572013-06-18 17:01:40 -07001464 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1465 OMX_MAX_STRINGNAME_SIZE)) {
1466 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1467 output_capability=V4L2_PIX_FMT_VP8;
1468 eCompressionFormat = OMX_VIDEO_CodingVPX;
1469 codec_type_parse = CODEC_TYPE_VP8;
1470 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001471#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001472 strcat(inputfilename, "ivf");
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001473#endif
1474
Arun Menon906de572013-06-18 17:01:40 -07001475 } else {
1476 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1477 eRet = OMX_ErrorInvalidComponentName;
1478 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001479#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001480 inputBufferFile1 = fopen (inputfilename, "ab");
1481 if (output_capability == V4L2_PIX_FMT_VP8) {
1482 struct ivf_file_header {
1483 OMX_U8 signature[4]; //='DKIF';
1484 OMX_U8 version ; //= 0;
1485 OMX_U8 headersize ; //= 32;
1486 OMX_U32 FourCC;
1487 OMX_U8 width;
1488 OMX_U8 height;
1489 OMX_U32 rate;
1490 OMX_U32 scale;
1491 OMX_U32 length;
1492 OMX_U8 unused[4];
1493 } file_header;
1494 memset((void *)&file_header,0,sizeof(file_header));
1495 file_header.signature[0] = 'D';
1496 file_header.signature[1] = 'K';
1497 file_header.signature[2] = 'I';
1498 file_header.signature[3] = 'F';
1499 file_header.version = 0;
1500 file_header.headersize = 32;
1501 file_header.FourCC = 0x30385056;
1502 if (inputBufferFile1) {
1503 fwrite((const char *)&file_header,
1504 sizeof(file_header),1,inputBufferFile1);
1505 }
1506 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001507#endif
Arun Menon906de572013-06-18 17:01:40 -07001508 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001509
Arun Menon906de572013-06-18 17:01:40 -07001510 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001511 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1512 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1513 if (!client_buffers.set_color_format(dest_color_format)) {
1514 DEBUG_PRINT_ERROR("\n Setting color format failed");
1515 eRet = OMX_ErrorInsufficientResources;
1516 }
1517
Arun Menon906de572013-06-18 17:01:40 -07001518 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001519
Arun Menon906de572013-06-18 17:01:40 -07001520 struct v4l2_capability cap;
1521 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1522 if (ret) {
1523 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
1524 /*TODO: How to handle this case */
1525 } else {
1526 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
1527 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1528 cap.bus_info, cap.version, cap.capabilities);
1529 }
1530 ret=0;
1531 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1532 fdesc.index=0;
1533 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1534 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
1535 fdesc.pixelformat, fdesc.flags);
1536 fdesc.index++;
1537 }
1538 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1539 fdesc.index=0;
1540 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001541
Arun Menon906de572013-06-18 17:01:40 -07001542 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
1543 fdesc.pixelformat, fdesc.flags);
1544 fdesc.index++;
1545 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001546 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001547 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1548 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1549 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1550 fmt.fmt.pix_mp.pixelformat = output_capability;
1551 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1552 if (ret) {
1553 /*TODO: How to handle this case */
1554 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
1555 return OMX_ErrorInsufficientResources;
1556 }
1557 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
1558 if (codec_ambiguous) {
1559 if (output_capability == V4L2_PIX_FMT_DIVX) {
1560 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001561
Arun Menon906de572013-06-18 17:01:40 -07001562 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1563 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1564 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1565 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1566 } else {
1567 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1568 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001569
Arun Menon906de572013-06-18 17:01:40 -07001570 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1571 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1572 if (ret) {
1573 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1574 }
1575 } else {
1576 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1577 }
1578 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001579
Arun Menon906de572013-06-18 17:01:40 -07001580 //Get the hardware capabilities
1581 memset((void *)&frmsize,0,sizeof(frmsize));
1582 frmsize.index = 0;
1583 frmsize.pixel_format = output_capability;
1584 ret = ioctl(drv_ctx.video_driver_fd,
1585 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1586 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1587 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1588 return OMX_ErrorHardware;
1589 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001590
Arun Menon906de572013-06-18 17:01:40 -07001591 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1592 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1593 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1594 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1595 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1596 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001597
Arun Menon906de572013-06-18 17:01:40 -07001598 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1599 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1600 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1601 fmt.fmt.pix_mp.pixelformat = capture_capability;
1602 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1603 if (ret) {
1604 /*TODO: How to handle this case */
1605 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
1606 }
1607 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
1608 if (secure_mode) {
1609 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1610 control.value = 1;
1611 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1612 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1613 if (ret) {
1614 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1615 return OMX_ErrorInsufficientResources;
1616 }
1617 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001618
Arun Menon906de572013-06-18 17:01:40 -07001619 /*Get the Buffer requirements for input and output ports*/
1620 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1621 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1622 if (secure_mode) {
1623 drv_ctx.op_buf.alignment=SZ_1M;
1624 drv_ctx.ip_buf.alignment=SZ_1M;
1625 } else {
1626 drv_ctx.op_buf.alignment=SZ_4K;
1627 drv_ctx.ip_buf.alignment=SZ_4K;
1628 }
1629 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1630 drv_ctx.extradata = 0;
1631 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1632 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1633 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1634 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1635 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001636
Vinay Kalia5713bb32013-01-16 18:39:59 -08001637 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001638#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001639 if (eRet == OMX_ErrorNone && !secure_mode)
1640 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001641#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001642 eRet=get_buffer_req(&drv_ctx.ip_buf);
1643 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1644 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001645 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1646 if (m_frame_parser.mutils == NULL) {
1647 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001648
Arun Menon906de572013-06-18 17:01:40 -07001649 if (m_frame_parser.mutils == NULL) {
1650 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1651 eRet = OMX_ErrorInsufficientResources;
1652 } else {
1653 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1654 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1655 h264_scratch.nFilledLen = 0;
1656 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001657
Arun Menon906de572013-06-18 17:01:40 -07001658 if (h264_scratch.pBuffer == NULL) {
1659 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1660 return OMX_ErrorInsufficientResources;
1661 }
1662 m_frame_parser.mutils->initialize_frame_checking_environment();
1663 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1664 }
1665 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001666
Arun Menon906de572013-06-18 17:01:40 -07001667 h264_parser = new h264_stream_parser();
1668 if (!h264_parser) {
1669 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1670 eRet = OMX_ErrorInsufficientResources;
1671 }
1672 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001673
Arun Menon906de572013-06-18 17:01:40 -07001674 if (pipe(fds)) {
1675 DEBUG_PRINT_ERROR("pipe creation failed\n");
1676 eRet = OMX_ErrorInsufficientResources;
1677 } else {
1678 int temp1[2];
1679 if (fds[0] == 0 || fds[1] == 0) {
1680 if (pipe (temp1)) {
1681 DEBUG_PRINT_ERROR("pipe creation failed\n");
1682 return OMX_ErrorInsufficientResources;
1683 }
1684 //close (fds[0]);
1685 //close (fds[1]);
1686 fds[0] = temp1 [0];
1687 fds[1] = temp1 [1];
1688 }
1689 m_pipe_in = fds[0];
1690 m_pipe_out = fds[1];
1691 msg_thread_created = true;
1692 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001693
Arun Menon906de572013-06-18 17:01:40 -07001694 if (r < 0) {
1695 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1696 msg_thread_created = false;
1697 eRet = OMX_ErrorInsufficientResources;
1698 }
1699 }
1700 }
1701
1702 if (eRet != OMX_ErrorNone) {
1703 DEBUG_PRINT_ERROR("\n Component Init Failed");
1704 } else {
1705 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1706 }
1707 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1708 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001709}
1710
1711/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001712 FUNCTION
1713 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001714
Arun Menon906de572013-06-18 17:01:40 -07001715 DESCRIPTION
1716 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001717
Arun Menon906de572013-06-18 17:01:40 -07001718 PARAMETERS
1719 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001720
Arun Menon906de572013-06-18 17:01:40 -07001721 RETURN VALUE
1722 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001723
Arun Menon906de572013-06-18 17:01:40 -07001724 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001725OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001726(
1727 OMX_IN OMX_HANDLETYPE hComp,
1728 OMX_OUT OMX_STRING componentName,
1729 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1730 OMX_OUT OMX_VERSIONTYPE* specVersion,
1731 OMX_OUT OMX_UUIDTYPE* componentUUID
1732 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001733{
Arun Menon906de572013-06-18 17:01:40 -07001734 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001735 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1736 return OMX_ErrorInvalidState;
1737 }
Arun Menon906de572013-06-18 17:01:40 -07001738 /* TBD -- Return the proper version */
1739 if (specVersion) {
1740 specVersion->nVersion = OMX_SPEC_VERSION;
1741 }
1742 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001743}
1744/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001745 FUNCTION
1746 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001747
Arun Menon906de572013-06-18 17:01:40 -07001748 DESCRIPTION
1749 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001750
Arun Menon906de572013-06-18 17:01:40 -07001751 PARAMETERS
1752 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001753
Arun Menon906de572013-06-18 17:01:40 -07001754 RETURN VALUE
1755 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001756
Arun Menon906de572013-06-18 17:01:40 -07001757 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001758OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001759 OMX_IN OMX_COMMANDTYPE cmd,
1760 OMX_IN OMX_U32 param1,
1761 OMX_IN OMX_PTR cmdData
1762 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001763{
1764 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001765 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001766 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1767 return OMX_ErrorInvalidState;
1768 }
1769 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001770 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
1771 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
1772 "to invalid port: %lu", param1);
1773 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001774 }
1775 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1776 sem_wait(&m_cmd_lock);
1777 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1778 return OMX_ErrorNone;
1779}
1780
1781/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001782 FUNCTION
1783 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001784
Arun Menon906de572013-06-18 17:01:40 -07001785 DESCRIPTION
1786 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001787
Arun Menon906de572013-06-18 17:01:40 -07001788 PARAMETERS
1789 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001790
Arun Menon906de572013-06-18 17:01:40 -07001791 RETURN VALUE
1792 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001793
Arun Menon906de572013-06-18 17:01:40 -07001794 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001795OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001796 OMX_IN OMX_COMMANDTYPE cmd,
1797 OMX_IN OMX_U32 param1,
1798 OMX_IN OMX_PTR cmdData
1799 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001800{
Arun Menon906de572013-06-18 17:01:40 -07001801 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1802 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1803 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001804
Arun Menon906de572013-06-18 17:01:40 -07001805 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1806 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1807 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001808
Arun Menon906de572013-06-18 17:01:40 -07001809 if (cmd == OMX_CommandStateSet) {
1810 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1811 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1812 /***************************/
1813 /* Current State is Loaded */
1814 /***************************/
1815 if (m_state == OMX_StateLoaded) {
1816 if (eState == OMX_StateIdle) {
1817 //if all buffers are allocated or all ports disabled
1818 if (allocate_done() ||
1819 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
1820 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1821 } else {
1822 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1823 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1824 // Skip the event notification
1825 bFlag = 0;
1826 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001827 }
Arun Menon906de572013-06-18 17:01:40 -07001828 /* Requesting transition from Loaded to Loaded */
1829 else if (eState == OMX_StateLoaded) {
1830 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1831 post_event(OMX_EventError,OMX_ErrorSameState,\
1832 OMX_COMPONENT_GENERATE_EVENT);
1833 eRet = OMX_ErrorSameState;
1834 }
1835 /* Requesting transition from Loaded to WaitForResources */
1836 else if (eState == OMX_StateWaitForResources) {
1837 /* Since error is None , we will post an event
1838 at the end of this function definition */
1839 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1840 }
1841 /* Requesting transition from Loaded to Executing */
1842 else if (eState == OMX_StateExecuting) {
1843 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1844 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1845 OMX_COMPONENT_GENERATE_EVENT);
1846 eRet = OMX_ErrorIncorrectStateTransition;
1847 }
1848 /* Requesting transition from Loaded to Pause */
1849 else if (eState == OMX_StatePause) {
1850 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1851 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1852 OMX_COMPONENT_GENERATE_EVENT);
1853 eRet = OMX_ErrorIncorrectStateTransition;
1854 }
1855 /* Requesting transition from Loaded to Invalid */
1856 else if (eState == OMX_StateInvalid) {
1857 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1858 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1859 eRet = OMX_ErrorInvalidState;
1860 } else {
1861 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1862 eState);
1863 eRet = OMX_ErrorBadParameter;
1864 }
1865 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001866
Arun Menon906de572013-06-18 17:01:40 -07001867 /***************************/
1868 /* Current State is IDLE */
1869 /***************************/
1870 else if (m_state == OMX_StateIdle) {
1871 if (eState == OMX_StateLoaded) {
1872 if (release_done()) {
1873 /*
1874 Since error is None , we will post an event at the end
1875 of this function definition
1876 */
1877 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
1878 } else {
1879 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
1880 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1881 // Skip the event notification
1882 bFlag = 0;
1883 }
1884 }
1885 /* Requesting transition from Idle to Executing */
1886 else if (eState == OMX_StateExecuting) {
1887 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1888 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1889 bFlag = 1;
1890 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1891 m_state=OMX_StateExecuting;
1892 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
1893 }
1894 /* Requesting transition from Idle to Idle */
1895 else if (eState == OMX_StateIdle) {
1896 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
1897 post_event(OMX_EventError,OMX_ErrorSameState,\
1898 OMX_COMPONENT_GENERATE_EVENT);
1899 eRet = OMX_ErrorSameState;
1900 }
1901 /* Requesting transition from Idle to WaitForResources */
1902 else if (eState == OMX_StateWaitForResources) {
1903 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
1904 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1905 OMX_COMPONENT_GENERATE_EVENT);
1906 eRet = OMX_ErrorIncorrectStateTransition;
1907 }
1908 /* Requesting transition from Idle to Pause */
1909 else if (eState == OMX_StatePause) {
1910 /*To pause the Video core we need to start the driver*/
1911 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
1912 NULL) < */0) {
1913 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
1914 omx_report_error ();
1915 eRet = OMX_ErrorHardware;
1916 } else {
1917 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1918 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
1919 bFlag = 0;
1920 }
1921 }
1922 /* Requesting transition from Idle to Invalid */
1923 else if (eState == OMX_StateInvalid) {
1924 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
1925 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1926 eRet = OMX_ErrorInvalidState;
1927 } else {
1928 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
1929 eRet = OMX_ErrorBadParameter;
1930 }
1931 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001932
Arun Menon906de572013-06-18 17:01:40 -07001933 /******************************/
1934 /* Current State is Executing */
1935 /******************************/
1936 else if (m_state == OMX_StateExecuting) {
1937 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
1938 /* Requesting transition from Executing to Idle */
1939 if (eState == OMX_StateIdle) {
1940 /* Since error is None , we will post an event
1941 at the end of this function definition
1942 */
1943 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
1944 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1945 if (!sem_posted) {
1946 sem_posted = 1;
1947 sem_post (&m_cmd_lock);
1948 execute_omx_flush(OMX_ALL);
1949 }
1950 bFlag = 0;
1951 }
1952 /* Requesting transition from Executing to Paused */
1953 else if (eState == OMX_StatePause) {
1954 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
1955 m_state = OMX_StatePause;
1956 bFlag = 1;
1957 }
1958 /* Requesting transition from Executing to Loaded */
1959 else if (eState == OMX_StateLoaded) {
1960 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
1961 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1962 OMX_COMPONENT_GENERATE_EVENT);
1963 eRet = OMX_ErrorIncorrectStateTransition;
1964 }
1965 /* Requesting transition from Executing to WaitForResources */
1966 else if (eState == OMX_StateWaitForResources) {
1967 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
1968 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1969 OMX_COMPONENT_GENERATE_EVENT);
1970 eRet = OMX_ErrorIncorrectStateTransition;
1971 }
1972 /* Requesting transition from Executing to Executing */
1973 else if (eState == OMX_StateExecuting) {
1974 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
1975 post_event(OMX_EventError,OMX_ErrorSameState,\
1976 OMX_COMPONENT_GENERATE_EVENT);
1977 eRet = OMX_ErrorSameState;
1978 }
1979 /* Requesting transition from Executing to Invalid */
1980 else if (eState == OMX_StateInvalid) {
1981 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
1982 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1983 eRet = OMX_ErrorInvalidState;
1984 } else {
1985 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
1986 eRet = OMX_ErrorBadParameter;
1987 }
1988 }
1989 /***************************/
1990 /* Current State is Pause */
1991 /***************************/
1992 else if (m_state == OMX_StatePause) {
1993 /* Requesting transition from Pause to Executing */
1994 if (eState == OMX_StateExecuting) {
1995 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
1996 m_state = OMX_StateExecuting;
1997 bFlag = 1;
1998 }
1999 /* Requesting transition from Pause to Idle */
2000 else if (eState == OMX_StateIdle) {
2001 /* Since error is None , we will post an event
2002 at the end of this function definition */
2003 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2004 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2005 if (!sem_posted) {
2006 sem_posted = 1;
2007 sem_post (&m_cmd_lock);
2008 execute_omx_flush(OMX_ALL);
2009 }
2010 bFlag = 0;
2011 }
2012 /* Requesting transition from Pause to loaded */
2013 else if (eState == OMX_StateLoaded) {
2014 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2015 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2016 OMX_COMPONENT_GENERATE_EVENT);
2017 eRet = OMX_ErrorIncorrectStateTransition;
2018 }
2019 /* Requesting transition from Pause to WaitForResources */
2020 else if (eState == OMX_StateWaitForResources) {
2021 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2022 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2023 OMX_COMPONENT_GENERATE_EVENT);
2024 eRet = OMX_ErrorIncorrectStateTransition;
2025 }
2026 /* Requesting transition from Pause to Pause */
2027 else if (eState == OMX_StatePause) {
2028 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2029 post_event(OMX_EventError,OMX_ErrorSameState,\
2030 OMX_COMPONENT_GENERATE_EVENT);
2031 eRet = OMX_ErrorSameState;
2032 }
2033 /* Requesting transition from Pause to Invalid */
2034 else if (eState == OMX_StateInvalid) {
2035 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2036 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2037 eRet = OMX_ErrorInvalidState;
2038 } else {
2039 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2040 eRet = OMX_ErrorBadParameter;
2041 }
2042 }
2043 /***************************/
2044 /* Current State is WaitForResources */
2045 /***************************/
2046 else if (m_state == OMX_StateWaitForResources) {
2047 /* Requesting transition from WaitForResources to Loaded */
2048 if (eState == OMX_StateLoaded) {
2049 /* Since error is None , we will post an event
2050 at the end of this function definition */
2051 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2052 }
2053 /* Requesting transition from WaitForResources to WaitForResources */
2054 else if (eState == OMX_StateWaitForResources) {
2055 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2056 post_event(OMX_EventError,OMX_ErrorSameState,
2057 OMX_COMPONENT_GENERATE_EVENT);
2058 eRet = OMX_ErrorSameState;
2059 }
2060 /* Requesting transition from WaitForResources to Executing */
2061 else if (eState == OMX_StateExecuting) {
2062 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2063 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2064 OMX_COMPONENT_GENERATE_EVENT);
2065 eRet = OMX_ErrorIncorrectStateTransition;
2066 }
2067 /* Requesting transition from WaitForResources to Pause */
2068 else if (eState == OMX_StatePause) {
2069 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2070 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2071 OMX_COMPONENT_GENERATE_EVENT);
2072 eRet = OMX_ErrorIncorrectStateTransition;
2073 }
2074 /* Requesting transition from WaitForResources to Invalid */
2075 else if (eState == OMX_StateInvalid) {
2076 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2077 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2078 eRet = OMX_ErrorInvalidState;
2079 }
2080 /* Requesting transition from WaitForResources to Loaded -
2081 is NOT tested by Khronos TS */
2082
2083 } else {
2084 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2085 eRet = OMX_ErrorBadParameter;
2086 }
2087 }
2088 /********************************/
2089 /* Current State is Invalid */
2090 /*******************************/
2091 else if (m_state == OMX_StateInvalid) {
2092 /* State Transition from Inavlid to any state */
2093 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2094 || OMX_StateIdle || OMX_StateExecuting
2095 || OMX_StatePause || OMX_StateInvalid)) {
2096 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2097 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2098 OMX_COMPONENT_GENERATE_EVENT);
2099 eRet = OMX_ErrorInvalidState;
2100 }
2101 } else if (cmd == OMX_CommandFlush) {
2102 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
2103 "with param1: %lu", param1);
2104 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2105 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2106 }
2107 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2108 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2109 }
2110 if (!sem_posted) {
2111 sem_posted = 1;
2112 DEBUG_PRINT_LOW("\n Set the Semaphore");
2113 sem_post (&m_cmd_lock);
2114 execute_omx_flush(param1);
2115 }
2116 bFlag = 0;
2117 } else if ( cmd == OMX_CommandPortEnable) {
2118 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
2119 "with param1: %lu", param1);
2120 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2121 m_inp_bEnabled = OMX_TRUE;
2122
2123 if ( (m_state == OMX_StateLoaded &&
2124 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2125 || allocate_input_done()) {
2126 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2127 OMX_COMPONENT_GENERATE_EVENT);
2128 } else {
2129 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2130 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2131 // Skip the event notification
2132 bFlag = 0;
2133 }
2134 }
2135 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2136 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2137 m_out_bEnabled = OMX_TRUE;
2138
2139 if ( (m_state == OMX_StateLoaded &&
2140 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2141 || (allocate_output_done())) {
2142 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2143 OMX_COMPONENT_GENERATE_EVENT);
2144
2145 } else {
2146 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2147 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2148 // Skip the event notification
2149 bFlag = 0;
2150 }
2151 }
2152 } else if (cmd == OMX_CommandPortDisable) {
2153 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
2154 "with param1: %lu", param1);
2155 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2156 m_inp_bEnabled = OMX_FALSE;
2157 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2158 && release_input_done()) {
2159 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2160 OMX_COMPONENT_GENERATE_EVENT);
2161 } else {
2162 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2163 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2164 if (!sem_posted) {
2165 sem_posted = 1;
2166 sem_post (&m_cmd_lock);
2167 }
2168 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2169 }
2170
2171 // Skip the event notification
2172 bFlag = 0;
2173 }
2174 }
2175 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2176 m_out_bEnabled = OMX_FALSE;
2177 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2178 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2179 && release_output_done()) {
2180 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2181 OMX_COMPONENT_GENERATE_EVENT);
2182 } else {
2183 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2184 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2185 if (!sem_posted) {
2186 sem_posted = 1;
2187 sem_post (&m_cmd_lock);
2188 }
2189 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2190 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2191 }
2192 // Skip the event notification
2193 bFlag = 0;
2194
2195 }
2196 }
2197 } else {
2198 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2199 eRet = OMX_ErrorNotImplemented;
2200 }
2201 if (eRet == OMX_ErrorNone && bFlag) {
2202 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2203 }
2204 if (!sem_posted) {
2205 sem_post(&m_cmd_lock);
2206 }
2207
2208 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002209}
2210
2211/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002212 FUNCTION
2213 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002214
Arun Menon906de572013-06-18 17:01:40 -07002215 DESCRIPTION
2216 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002217
Arun Menon906de572013-06-18 17:01:40 -07002218 PARAMETERS
2219 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002220
Arun Menon906de572013-06-18 17:01:40 -07002221 RETURN VALUE
2222 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002223
Arun Menon906de572013-06-18 17:01:40 -07002224 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002225bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2226{
Arun Menon906de572013-06-18 17:01:40 -07002227 bool bRet = false;
2228 struct v4l2_plane plane;
2229 struct v4l2_buffer v4l2_buf;
2230 struct v4l2_decoder_cmd dec;
2231 DEBUG_PRINT_LOW("in %s, flushing %d", __func__, flushType);
2232 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2233 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002234
Arun Menon906de572013-06-18 17:01:40 -07002235 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002236
Arun Menon906de572013-06-18 17:01:40 -07002237 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2238 output_flush_progress = true;
2239 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2240 } else {
2241 /* XXX: The driver/hardware does not support flushing of individual ports
2242 * in all states. So we pretty much need to flush both ports internally,
2243 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2244 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2245 * we automatically omit sending the FLUSH done for the "opposite" port. */
2246 input_flush_progress = true;
2247 output_flush_progress = true;
2248 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2249 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002250
Arun Menon906de572013-06-18 17:01:40 -07002251 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
2252 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
2253 bRet = false;
2254 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002255
Arun Menon906de572013-06-18 17:01:40 -07002256 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002257}
2258/*=========================================================================
2259FUNCTION : execute_output_flush
2260
2261DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002262Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002263
2264PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002265None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002266
2267RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002268true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002269==========================================================================*/
2270bool omx_vdec::execute_output_flush()
2271{
Arun Menon906de572013-06-18 17:01:40 -07002272 unsigned p1 = 0; // Parameter - 1
2273 unsigned p2 = 0; // Parameter - 2
2274 unsigned ident = 0;
2275 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002276
Arun Menon906de572013-06-18 17:01:40 -07002277 /*Generate FBD for all Buffers in the FTBq*/
2278 pthread_mutex_lock(&m_lock);
2279 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2280 while (m_ftb_q.m_size) {
2281 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2282 m_ftb_q.m_size,pending_output_buffers);
2283 m_ftb_q.pop_entry(&p1,&p2,&ident);
2284 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
2285 if (ident == m_fill_output_msg ) {
2286 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2287 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2288 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2289 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002290 }
Arun Menon906de572013-06-18 17:01:40 -07002291 pthread_mutex_unlock(&m_lock);
2292 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002293
Arun Menon906de572013-06-18 17:01:40 -07002294 if (arbitrary_bytes) {
2295 prev_ts = LLONG_MAX;
2296 rst_prev_ts = true;
2297 }
2298 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2299 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002300}
2301/*=========================================================================
2302FUNCTION : execute_input_flush
2303
2304DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002305Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002306
2307PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002308None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002309
2310RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002311true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002312==========================================================================*/
2313bool omx_vdec::execute_input_flush()
2314{
Arun Menon906de572013-06-18 17:01:40 -07002315 unsigned i =0;
2316 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 EBD for all Buffers in the ETBq*/
2322 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002323
Arun Menon906de572013-06-18 17:01:40 -07002324 pthread_mutex_lock(&m_lock);
2325 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2326 while (m_etb_q.m_size) {
2327 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002328
Arun Menon906de572013-06-18 17:01:40 -07002329 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2330 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2331 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2332 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2333 pending_input_buffers++;
2334 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2335 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2336 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2337 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
2338 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2339 (OMX_BUFFERHEADERTYPE *)p1);
2340 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2341 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002342 }
Arun Menon906de572013-06-18 17:01:40 -07002343 time_stamp_dts.flush_timestamp();
2344 /*Check if Heap Buffers are to be flushed*/
2345 if (arbitrary_bytes && !(codec_config_flag)) {
2346 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2347 h264_scratch.nFilledLen = 0;
2348 nal_count = 0;
2349 look_ahead_nal = false;
2350 frame_count = 0;
2351 h264_last_au_ts = LLONG_MAX;
2352 h264_last_au_flags = 0;
2353 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2354 m_demux_entries = 0;
2355 DEBUG_PRINT_LOW("\n Initialize parser");
2356 if (m_frame_parser.mutils) {
2357 m_frame_parser.mutils->initialize_frame_checking_environment();
2358 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002359
Arun Menon906de572013-06-18 17:01:40 -07002360 while (m_input_pending_q.m_size) {
2361 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2362 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2363 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002364
Arun Menon906de572013-06-18 17:01:40 -07002365 if (psource_frame) {
2366 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2367 psource_frame = NULL;
2368 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002369
Arun Menon906de572013-06-18 17:01:40 -07002370 if (pdest_frame) {
2371 pdest_frame->nFilledLen = 0;
2372 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2373 (unsigned int)NULL);
2374 pdest_frame = NULL;
2375 }
2376 m_frame_parser.flush();
2377 } else if (codec_config_flag) {
2378 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2379 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002380 }
Arun Menon906de572013-06-18 17:01:40 -07002381 pthread_mutex_unlock(&m_lock);
2382 input_flush_progress = false;
2383 if (!arbitrary_bytes) {
2384 prev_ts = LLONG_MAX;
2385 rst_prev_ts = true;
2386 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002387#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002388 if (m_debug_timestamp) {
2389 m_timestamp_list.reset_ts_list();
2390 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002391#endif
Arun Menon906de572013-06-18 17:01:40 -07002392 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2393 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002394}
2395
2396
2397/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002398 FUNCTION
2399 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002400
Arun Menon906de572013-06-18 17:01:40 -07002401 DESCRIPTION
2402 Send the event to decoder pipe. This is needed to generate the callbacks
2403 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002404
Arun Menon906de572013-06-18 17:01:40 -07002405 PARAMETERS
2406 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002407
Arun Menon906de572013-06-18 17:01:40 -07002408 RETURN VALUE
2409 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002410
Arun Menon906de572013-06-18 17:01:40 -07002411 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002412bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002413 unsigned int p2,
2414 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002415{
Arun Menon906de572013-06-18 17:01:40 -07002416 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002417
2418
Arun Menon906de572013-06-18 17:01:40 -07002419 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002420
Arun Menon906de572013-06-18 17:01:40 -07002421 if (id == m_fill_output_msg ||
2422 id == OMX_COMPONENT_GENERATE_FBD) {
2423 m_ftb_q.insert_entry(p1,p2,id);
2424 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2425 id == OMX_COMPONENT_GENERATE_EBD ||
2426 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2427 m_etb_q.insert_entry(p1,p2,id);
2428 } else {
2429 m_cmd_q.insert_entry(p1,p2,id);
2430 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002431
Arun Menon906de572013-06-18 17:01:40 -07002432 bRet = true;
2433 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2434 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002435
Arun Menon906de572013-06-18 17:01:40 -07002436 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002437
Arun Menon906de572013-06-18 17:01:40 -07002438 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002439}
2440
2441OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2442{
Arun Menon906de572013-06-18 17:01:40 -07002443 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2444 if (!profileLevelType)
2445 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002446
Arun Menon906de572013-06-18 17:01:40 -07002447 if (profileLevelType->nPortIndex == 0) {
2448 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2449 if (profileLevelType->nProfileIndex == 0) {
2450 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2451 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002452
Arun Menon906de572013-06-18 17:01:40 -07002453 } else if (profileLevelType->nProfileIndex == 1) {
2454 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2455 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2456 } else if (profileLevelType->nProfileIndex == 2) {
2457 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2458 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2459 } else {
2460 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
2461 profileLevelType->nProfileIndex);
2462 eRet = OMX_ErrorNoMore;
2463 }
2464 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2465 if (profileLevelType->nProfileIndex == 0) {
2466 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2467 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2468 } else {
2469 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2470 eRet = OMX_ErrorNoMore;
2471 }
2472 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2473 if (profileLevelType->nProfileIndex == 0) {
2474 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2475 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2476 } else if (profileLevelType->nProfileIndex == 1) {
2477 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2478 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2479 } else {
2480 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2481 eRet = OMX_ErrorNoMore;
2482 }
2483 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2484 eRet = OMX_ErrorNoMore;
2485 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2486 if (profileLevelType->nProfileIndex == 0) {
2487 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2488 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2489 } else if (profileLevelType->nProfileIndex == 1) {
2490 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2491 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2492 } else {
2493 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2494 eRet = OMX_ErrorNoMore;
2495 }
2496 } else {
2497 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s\n", drv_ctx.kind);
2498 eRet = OMX_ErrorNoMore;
2499 }
2500 } else {
2501 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex);
2502 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002503 }
Arun Menon906de572013-06-18 17:01:40 -07002504 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002505}
2506
2507/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002508 FUNCTION
2509 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002510
Arun Menon906de572013-06-18 17:01:40 -07002511 DESCRIPTION
2512 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002513
Arun Menon906de572013-06-18 17:01:40 -07002514 PARAMETERS
2515 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002516
Arun Menon906de572013-06-18 17:01:40 -07002517 RETURN VALUE
2518 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002519
Arun Menon906de572013-06-18 17:01:40 -07002520 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002521OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002522 OMX_IN OMX_INDEXTYPE paramIndex,
2523 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002524{
2525 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2526
2527 DEBUG_PRINT_LOW("get_parameter: \n");
Arun Menon906de572013-06-18 17:01:40 -07002528 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002529 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2530 return OMX_ErrorInvalidState;
2531 }
Arun Menon906de572013-06-18 17:01:40 -07002532 if (paramData == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002533 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2534 return OMX_ErrorBadParameter;
2535 }
Arun Menon906de572013-06-18 17:01:40 -07002536 switch ((unsigned long)paramIndex) {
2537 case OMX_IndexParamPortDefinition: {
2538 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2539 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2540 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2541 eRet = update_portdef(portDefn);
2542 if (eRet == OMX_ErrorNone)
2543 m_port_def = *portDefn;
2544 break;
2545 }
2546 case OMX_IndexParamVideoInit: {
2547 OMX_PORT_PARAM_TYPE *portParamType =
2548 (OMX_PORT_PARAM_TYPE *) paramData;
2549 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002550
Arun Menon906de572013-06-18 17:01:40 -07002551 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2552 portParamType->nSize = sizeof(portParamType);
2553 portParamType->nPorts = 2;
2554 portParamType->nStartPortNumber = 0;
2555 break;
2556 }
2557 case OMX_IndexParamVideoPortFormat: {
2558 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2559 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2560 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002561
Arun Menon906de572013-06-18 17:01:40 -07002562 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2563 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002564
Arun Menon906de572013-06-18 17:01:40 -07002565 if (0 == portFmt->nPortIndex) {
2566 if (0 == portFmt->nIndex) {
2567 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2568 portFmt->eCompressionFormat = eCompressionFormat;
2569 } else {
2570 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2571 " NoMore compression formats\n");
2572 eRet = OMX_ErrorNoMore;
2573 }
2574 } else if (1 == portFmt->nPortIndex) {
2575 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002576
Arun Menon906de572013-06-18 17:01:40 -07002577 if (0 == portFmt->nIndex)
2578 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2579 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2580 else if (1 == portFmt->nIndex)
2581 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2582 else {
2583 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2584 " NoMore Color formats\n");
2585 eRet = OMX_ErrorNoMore;
2586 }
2587 DEBUG_PRINT_LOW("returning %d\n", portFmt->eColorFormat);
2588 } else {
2589 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2590 (int)portFmt->nPortIndex);
2591 eRet = OMX_ErrorBadPortIndex;
2592 }
2593 break;
2594 }
2595 /*Component should support this port definition*/
2596 case OMX_IndexParamAudioInit: {
2597 OMX_PORT_PARAM_TYPE *audioPortParamType =
2598 (OMX_PORT_PARAM_TYPE *) paramData;
2599 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2600 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2601 audioPortParamType->nSize = sizeof(audioPortParamType);
2602 audioPortParamType->nPorts = 0;
2603 audioPortParamType->nStartPortNumber = 0;
2604 break;
2605 }
2606 /*Component should support this port definition*/
2607 case OMX_IndexParamImageInit: {
2608 OMX_PORT_PARAM_TYPE *imagePortParamType =
2609 (OMX_PORT_PARAM_TYPE *) paramData;
2610 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2611 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2612 imagePortParamType->nSize = sizeof(imagePortParamType);
2613 imagePortParamType->nPorts = 0;
2614 imagePortParamType->nStartPortNumber = 0;
2615 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002616
Arun Menon906de572013-06-18 17:01:40 -07002617 }
2618 /*Component should support this port definition*/
2619 case OMX_IndexParamOtherInit: {
2620 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2621 paramIndex);
2622 eRet =OMX_ErrorUnsupportedIndex;
2623 break;
2624 }
2625 case OMX_IndexParamStandardComponentRole: {
2626 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2627 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2628 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2629 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002630
Arun Menon906de572013-06-18 17:01:40 -07002631 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2632 paramIndex);
2633 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2634 OMX_MAX_STRINGNAME_SIZE);
2635 break;
2636 }
2637 /* Added for parameter test */
2638 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002639
Arun Menon906de572013-06-18 17:01:40 -07002640 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2641 (OMX_PRIORITYMGMTTYPE *) paramData;
2642 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2643 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2644 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002645
Arun Menon906de572013-06-18 17:01:40 -07002646 break;
2647 }
2648 /* Added for parameter test */
2649 case OMX_IndexParamCompBufferSupplier: {
2650 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2651 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2652 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002653
Arun Menon906de572013-06-18 17:01:40 -07002654 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2655 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2656 if (0 == bufferSupplierType->nPortIndex)
2657 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2658 else if (1 == bufferSupplierType->nPortIndex)
2659 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2660 else
2661 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002662
2663
Arun Menon906de572013-06-18 17:01:40 -07002664 break;
2665 }
2666 case OMX_IndexParamVideoAvc: {
2667 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2668 paramIndex);
2669 break;
2670 }
2671 case OMX_IndexParamVideoH263: {
2672 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2673 paramIndex);
2674 break;
2675 }
2676 case OMX_IndexParamVideoMpeg4: {
2677 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2678 paramIndex);
2679 break;
2680 }
2681 case OMX_IndexParamVideoMpeg2: {
2682 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2683 paramIndex);
2684 break;
2685 }
2686 case OMX_IndexParamVideoProfileLevelQuerySupported: {
2687 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2688 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2689 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2690 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2691 break;
2692 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002693#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002694 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
2695 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2696 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2697 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002698
Arun Menon906de572013-06-18 17:01:40 -07002699 if (secure_mode) {
2700 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2701 GRALLOC_USAGE_PRIVATE_UNCACHED);
2702 } else {
2703 nativeBuffersUsage->nUsage =
2704 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2705 GRALLOC_USAGE_PRIVATE_UNCACHED);
2706 }
2707 } else {
2708 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
2709 eRet = OMX_ErrorBadParameter;
2710 }
2711 }
2712 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002713#endif
2714
Arun Menon906de572013-06-18 17:01:40 -07002715 default: {
2716 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2717 eRet =OMX_ErrorUnsupportedIndex;
2718 }
2719
Shalaj Jain273b3e02012-06-22 19:08:03 -07002720 }
2721
Arun Menon906de572013-06-18 17:01:40 -07002722 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
2723 drv_ctx.video_resolution.frame_width,
2724 drv_ctx.video_resolution.frame_height,
2725 drv_ctx.video_resolution.stride,
2726 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002727
Arun Menon906de572013-06-18 17:01:40 -07002728 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002729}
2730
2731#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2732OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2733{
2734 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2735 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2736 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2737
Arun Menon906de572013-06-18 17:01:40 -07002738 if ((params == NULL) ||
2739 (params->nativeBuffer == NULL) ||
2740 (params->nativeBuffer->handle == NULL) ||
2741 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002742 return OMX_ErrorBadParameter;
2743 m_use_android_native_buffers = OMX_TRUE;
2744 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2745 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002746 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 -07002747 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002748 if (!secure_mode) {
2749 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002750 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002751 if (buffer == MAP_FAILED) {
2752 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2753 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002754 }
2755 }
2756 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2757 } else {
2758 eRet = OMX_ErrorBadParameter;
2759 }
2760 return eRet;
2761}
2762#endif
2763/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002764 FUNCTION
2765 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002766
Arun Menon906de572013-06-18 17:01:40 -07002767 DESCRIPTION
2768 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002769
Arun Menon906de572013-06-18 17:01:40 -07002770 PARAMETERS
2771 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002772
Arun Menon906de572013-06-18 17:01:40 -07002773 RETURN VALUE
2774 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002775
Arun Menon906de572013-06-18 17:01:40 -07002776 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002777OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002778 OMX_IN OMX_INDEXTYPE paramIndex,
2779 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002780{
2781 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002782 int ret=0;
2783 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002784 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002785 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
2786 return OMX_ErrorInvalidState;
2787 }
Arun Menon906de572013-06-18 17:01:40 -07002788 if (paramData == NULL) {
2789 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
2790 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002791 }
Arun Menon906de572013-06-18 17:01:40 -07002792 if ((m_state != OMX_StateLoaded) &&
2793 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2794 (m_out_bEnabled == OMX_TRUE) &&
2795 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2796 (m_inp_bEnabled == OMX_TRUE)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002797 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
2798 return OMX_ErrorIncorrectStateOperation;
2799 }
Arun Menon906de572013-06-18 17:01:40 -07002800 switch ((unsigned long)paramIndex) {
2801 case OMX_IndexParamPortDefinition: {
2802 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2803 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2804 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2805 //been called.
2806 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
2807 (int)portDefn->format.video.nFrameHeight,
2808 (int)portDefn->format.video.nFrameWidth);
2809 if (OMX_DirOutput == portDefn->eDir) {
2810 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
2811 m_display_id = portDefn->format.video.pNativeWindow;
2812 unsigned int buffer_size;
2813 if (!client_buffers.get_buffer_req(buffer_size)) {
2814 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
2815 eRet = OMX_ErrorBadParameter;
2816 } else {
2817 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
2818 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
2819 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
2820 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
2821 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
2822 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
2823 drv_ctx.extradata_info.buffer_size;
2824 eRet = set_buffer_req(&drv_ctx.op_buf);
2825 if (eRet == OMX_ErrorNone)
2826 m_port_def = *portDefn;
2827 } else {
2828 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
2829 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
2830 portDefn->nBufferCountActual, portDefn->nBufferSize);
2831 eRet = OMX_ErrorBadParameter;
2832 }
2833 }
2834 } else if (OMX_DirInput == portDefn->eDir) {
2835 bool port_format_changed = false;
2836 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
2837 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
2838 // Frame rate only should be set if this is a "known value" or to
2839 // activate ts prediction logic (arbitrary mode only) sending input
2840 // timestamps with max value (LLONG_MAX).
2841 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
2842 portDefn->format.video.xFramerate >> 16);
2843 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
2844 drv_ctx.frame_rate.fps_denominator);
2845 if (!drv_ctx.frame_rate.fps_numerator) {
2846 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
2847 drv_ctx.frame_rate.fps_numerator = 30;
2848 }
2849 if (drv_ctx.frame_rate.fps_denominator)
2850 drv_ctx.frame_rate.fps_numerator = (int)
2851 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
2852 drv_ctx.frame_rate.fps_denominator = 1;
2853 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
2854 drv_ctx.frame_rate.fps_numerator;
2855 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
2856 frm_int, drv_ctx.frame_rate.fps_numerator /
2857 (float)drv_ctx.frame_rate.fps_denominator);
2858 }
2859 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
2860 if (drv_ctx.video_resolution.frame_height !=
2861 portDefn->format.video.nFrameHeight ||
2862 drv_ctx.video_resolution.frame_width !=
2863 portDefn->format.video.nFrameWidth) {
2864 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
2865 portDefn->format.video.nFrameWidth,
2866 portDefn->format.video.nFrameHeight);
2867 port_format_changed = true;
2868 if (portDefn->format.video.nFrameHeight != 0x0 &&
2869 portDefn->format.video.nFrameWidth != 0x0) {
2870 update_resolution(portDefn->format.video.nFrameWidth,
2871 portDefn->format.video.nFrameHeight,
2872 portDefn->format.video.nFrameWidth,
2873 portDefn->format.video.nFrameHeight);
2874 eRet = is_video_session_supported();
2875 if (eRet)
2876 break;
2877 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2878 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2879 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2880 fmt.fmt.pix_mp.pixelformat = output_capability;
2881 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);
2882 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2883 if (ret) {
2884 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2885 eRet = OMX_ErrorUnsupportedSetting;
2886 } else
2887 eRet = get_buffer_req(&drv_ctx.op_buf);
2888 }
2889 }
2890 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
2891 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
2892 port_format_changed = true;
2893 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
2894 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
2895 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
2896 (~(buffer_prop->alignment - 1));
2897 eRet = set_buffer_req(buffer_prop);
2898 }
2899 if (false == port_format_changed) {
2900 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
2901 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
2902 portDefn->nBufferCountActual, portDefn->nBufferSize);
2903 eRet = OMX_ErrorBadParameter;
2904 }
2905 } else if (portDefn->eDir == OMX_DirMax) {
2906 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
2907 (int)portDefn->nPortIndex);
2908 eRet = OMX_ErrorBadPortIndex;
2909 }
2910 }
2911 break;
2912 case OMX_IndexParamVideoPortFormat: {
2913 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2914 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2915 int ret=0;
2916 struct v4l2_format fmt;
2917 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
2918 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002919
Arun Menon906de572013-06-18 17:01:40 -07002920 if (1 == portFmt->nPortIndex) {
2921 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_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 = capture_capability;
2925 enum vdec_output_fromat op_format;
2926 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
2927 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
2928 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
2929 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
2930 else if (portFmt->eColorFormat ==
2931 (OMX_COLOR_FORMATTYPE)
2932 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
2933 op_format = VDEC_YUV_FORMAT_TILE_4x2;
2934 else
2935 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002936
Arun Menon906de572013-06-18 17:01:40 -07002937 if (eRet == OMX_ErrorNone) {
2938 drv_ctx.output_format = op_format;
2939 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2940 if (ret) {
2941 DEBUG_PRINT_ERROR("\n Set output format failed");
2942 eRet = OMX_ErrorUnsupportedSetting;
2943 /*TODO: How to handle this case */
2944 } else {
2945 eRet = get_buffer_req(&drv_ctx.op_buf);
2946 }
2947 }
2948 if (eRet == OMX_ErrorNone) {
2949 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
2950 DEBUG_PRINT_ERROR("\n Set color format failed");
2951 eRet = OMX_ErrorBadParameter;
2952 }
2953 }
2954 }
2955 }
2956 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002957
Arun Menon906de572013-06-18 17:01:40 -07002958 case OMX_QcomIndexPortDefn: {
2959 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
2960 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
2961 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
2962 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002963
Arun Menon906de572013-06-18 17:01:40 -07002964 /* Input port */
2965 if (portFmt->nPortIndex == 0) {
2966 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
2967 if (secure_mode) {
2968 arbitrary_bytes = false;
2969 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
2970 eRet = OMX_ErrorUnsupportedSetting;
2971 } else {
2972 arbitrary_bytes = true;
2973 }
2974 } else if (portFmt->nFramePackingFormat ==
2975 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
2976 arbitrary_bytes = false;
2977 } else {
2978 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
2979 portFmt->nFramePackingFormat);
2980 eRet = OMX_ErrorUnsupportedSetting;
2981 }
2982 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
2983 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
2984 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
2985 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
2986 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
2987 m_out_mem_region_smi = OMX_TRUE;
2988 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
2989 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
2990 m_use_output_pmem = OMX_TRUE;
2991 }
2992 }
2993 }
2994 }
2995 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002996
Arun Menon906de572013-06-18 17:01:40 -07002997 case OMX_IndexParamStandardComponentRole: {
2998 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2999 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3000 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3001 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003002
Arun Menon906de572013-06-18 17:01:40 -07003003 if ((m_state == OMX_StateLoaded)&&
3004 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3005 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3006 } else {
3007 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3008 return OMX_ErrorIncorrectStateOperation;
3009 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003010
Arun Menon906de572013-06-18 17:01:40 -07003011 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3012 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3013 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3014 } else {
3015 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3016 eRet =OMX_ErrorUnsupportedSetting;
3017 }
3018 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3019 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3020 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3021 } else {
3022 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3023 eRet = OMX_ErrorUnsupportedSetting;
3024 }
3025 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3026 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3027 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3028 } else {
3029 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3030 eRet =OMX_ErrorUnsupportedSetting;
3031 }
3032 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3033 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3034 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3035 } else {
3036 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3037 eRet = OMX_ErrorUnsupportedSetting;
3038 }
3039 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3040 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3041 ) {
3042 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3043 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3044 } else {
3045 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3046 eRet =OMX_ErrorUnsupportedSetting;
3047 }
3048 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3049 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3050 ) {
3051 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3052 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3053 } else {
3054 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3055 eRet =OMX_ErrorUnsupportedSetting;
3056 }
3057 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3058 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3059 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3060 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3061 } else {
3062 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3063 eRet = OMX_ErrorUnsupportedSetting;
3064 }
3065 } else {
3066 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3067 eRet = OMX_ErrorInvalidComponentName;
3068 }
3069 break;
3070 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003071
Arun Menon906de572013-06-18 17:01:40 -07003072 case OMX_IndexParamPriorityMgmt: {
3073 if (m_state != OMX_StateLoaded) {
3074 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3075 return OMX_ErrorIncorrectStateOperation;
3076 }
3077 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
3078 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
3079 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003080
Arun Menon906de572013-06-18 17:01:40 -07003081 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
3082 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003083
Arun Menon906de572013-06-18 17:01:40 -07003084 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3085 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003086
Arun Menon906de572013-06-18 17:01:40 -07003087 break;
3088 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003089
Arun Menon906de572013-06-18 17:01:40 -07003090 case OMX_IndexParamCompBufferSupplier: {
3091 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3092 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3093 bufferSupplierType->eBufferSupplier);
3094 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3095 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003096
Arun Menon906de572013-06-18 17:01:40 -07003097 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003098
Arun Menon906de572013-06-18 17:01:40 -07003099 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003100
Arun Menon906de572013-06-18 17:01:40 -07003101 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003102
Arun Menon906de572013-06-18 17:01:40 -07003103 }
3104 case OMX_IndexParamVideoAvc: {
3105 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3106 paramIndex);
3107 break;
3108 }
3109 case OMX_IndexParamVideoH263: {
3110 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3111 paramIndex);
3112 break;
3113 }
3114 case OMX_IndexParamVideoMpeg4: {
3115 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3116 paramIndex);
3117 break;
3118 }
3119 case OMX_IndexParamVideoMpeg2: {
3120 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3121 paramIndex);
3122 break;
3123 }
3124 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3125 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3126 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3127 struct v4l2_control control;
3128 int pic_order,rc=0;
3129 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3130 pictureOrder->eOutputPictureOrder);
3131 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3132 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3133 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3134 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3135 time_stamp_dts.set_timestamp_reorder_mode(false);
3136 } else
3137 eRet = OMX_ErrorBadParameter;
3138 if (eRet == OMX_ErrorNone) {
3139 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3140 control.value = pic_order;
3141 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3142 if (rc) {
3143 DEBUG_PRINT_ERROR("\n Set picture order failed");
3144 eRet = OMX_ErrorUnsupportedSetting;
3145 }
3146 }
3147 break;
3148 }
3149 case OMX_QcomIndexParamConcealMBMapExtraData:
3150 if (!secure_mode)
3151 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3152 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3153 else {
3154 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3155 eRet = OMX_ErrorUnsupportedSetting;
3156 }
3157 break;
3158 case OMX_QcomIndexParamFrameInfoExtraData: {
3159 if (!secure_mode)
3160 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3161 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3162 else {
3163 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3164 eRet = OMX_ErrorUnsupportedSetting;
3165 }
3166 break;
3167 }
3168 case OMX_QcomIndexParamInterlaceExtraData:
3169 if (!secure_mode)
3170 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3171 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3172 else {
3173 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3174 eRet = OMX_ErrorUnsupportedSetting;
3175 }
3176 break;
3177 case OMX_QcomIndexParamH264TimeInfo:
3178 if (!secure_mode)
3179 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3180 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3181 else {
3182 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3183 eRet = OMX_ErrorUnsupportedSetting;
3184 }
3185 break;
3186 case OMX_QcomIndexParamVideoDivx: {
3187 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3188 }
3189 break;
3190 case OMX_QcomIndexPlatformPvt: {
3191 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3192 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3193 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3194 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3195 eRet = OMX_ErrorUnsupportedSetting;
3196 } else {
3197 m_out_pvt_entry_pmem = OMX_TRUE;
3198 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3199 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3200 m_use_output_pmem = OMX_TRUE;
3201 }
3202 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003203
Arun Menon906de572013-06-18 17:01:40 -07003204 }
3205 break;
3206 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3207 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3208 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3209 struct v4l2_control control;
3210 int rc;
3211 drv_ctx.idr_only_decoding = 1;
3212 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3213 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3214 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3215 if (rc) {
3216 DEBUG_PRINT_ERROR("\n Set picture order failed");
3217 eRet = OMX_ErrorUnsupportedSetting;
3218 } else {
3219 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3220 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3221 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3222 if (rc) {
3223 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3224 eRet = OMX_ErrorUnsupportedSetting;
3225 }
3226 /*Setting sync frame decoding on driver might change buffer
3227 * requirements so update them here*/
3228 if (get_buffer_req(&drv_ctx.ip_buf)) {
3229 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer i/p requirements");
3230 eRet = OMX_ErrorUnsupportedSetting;
3231 }
3232 if (get_buffer_req(&drv_ctx.op_buf)) {
3233 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer o/p requirements");
3234 eRet = OMX_ErrorUnsupportedSetting;
3235 }
3236 }
3237 }
3238 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003239
Arun Menon906de572013-06-18 17:01:40 -07003240 case OMX_QcomIndexParamIndexExtraDataType: {
3241 if (!secure_mode) {
3242 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3243 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3244 (extradataIndexType->bEnabled == OMX_TRUE) &&
3245 (extradataIndexType->nPortIndex == 1)) {
3246 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
3247 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003248
Arun Menon906de572013-06-18 17:01:40 -07003249 }
3250 }
3251 }
3252 break;
3253 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003254#ifndef SMOOTH_STREAMING_DISABLED
Arun Menon906de572013-06-18 17:01:40 -07003255 struct v4l2_control control;
3256 struct v4l2_format fmt;
3257 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3258 control.value = 1;
3259 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3260 if (rc < 0) {
3261 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3262 eRet = OMX_ErrorHardware;
3263 }
Arun Menonbc0922f2013-06-24 13:02:15 -07003264#else
Arun Menon906de572013-06-18 17:01:40 -07003265 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003266#endif
Arun Menon906de572013-06-18 17:01:40 -07003267 }
3268 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003269#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003270 /* Need to allow following two set_parameters even in Idle
3271 * state. This is ANDROID architecture which is not in sync
3272 * with openmax standard. */
3273 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3274 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3275 if (enableNativeBuffers) {
3276 m_enable_android_native_buffers = enableNativeBuffers->enable;
3277 }
3278 }
3279 break;
3280 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3281 eRet = use_android_native_buffer(hComp, paramData);
3282 }
3283 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003284#endif
Arun Menon906de572013-06-18 17:01:40 -07003285 case OMX_QcomIndexParamEnableTimeStampReorder: {
3286 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3287 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3288 if (reorder->bEnable == OMX_TRUE) {
3289 frm_int =0;
3290 time_stamp_dts.set_timestamp_reorder_mode(true);
3291 } else
3292 time_stamp_dts.set_timestamp_reorder_mode(false);
3293 } else {
3294 time_stamp_dts.set_timestamp_reorder_mode(false);
3295 if (reorder->bEnable == OMX_TRUE) {
3296 eRet = OMX_ErrorUnsupportedSetting;
3297 }
3298 }
3299 }
3300 break;
3301 case OMX_IndexParamVideoProfileLevelCurrent: {
3302 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3303 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3304 if (pParam) {
3305 m_profile_lvl.eProfile = pParam->eProfile;
3306 m_profile_lvl.eLevel = pParam->eLevel;
3307 }
3308 break;
Arun Menon888aa852013-05-30 11:24:42 -07003309
Arun Menon906de572013-06-18 17:01:40 -07003310 }
3311 default: {
3312 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3313 eRet = OMX_ErrorUnsupportedIndex;
3314 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003315 }
Arun Menon906de572013-06-18 17:01:40 -07003316 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003317}
3318
3319/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003320 FUNCTION
3321 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003322
Arun Menon906de572013-06-18 17:01:40 -07003323 DESCRIPTION
3324 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003325
Arun Menon906de572013-06-18 17:01:40 -07003326 PARAMETERS
3327 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003328
Arun Menon906de572013-06-18 17:01:40 -07003329 RETURN VALUE
3330 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003331
Arun Menon906de572013-06-18 17:01:40 -07003332 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003333OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003334 OMX_IN OMX_INDEXTYPE configIndex,
3335 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003336{
Arun Menon906de572013-06-18 17:01:40 -07003337 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003338
Arun Menon906de572013-06-18 17:01:40 -07003339 if (m_state == OMX_StateInvalid) {
3340 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003341 return OMX_ErrorInvalidState;
3342 }
Arun Menon906de572013-06-18 17:01:40 -07003343
3344 switch ((unsigned long)configIndex) {
3345 case OMX_QcomIndexConfigInterlaced: {
3346 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3347 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3348 if (configFmt->nPortIndex == 1) {
3349 if (configFmt->nIndex == 0) {
3350 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3351 } else if (configFmt->nIndex == 1) {
3352 configFmt->eInterlaceType =
3353 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3354 } else if (configFmt->nIndex == 2) {
3355 configFmt->eInterlaceType =
3356 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3357 } else {
3358 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3359 " NoMore Interlaced formats\n");
3360 eRet = OMX_ErrorNoMore;
3361 }
3362
3363 } else {
3364 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3365 (int)configFmt->nPortIndex);
3366 eRet = OMX_ErrorBadPortIndex;
3367 }
3368 break;
3369 }
3370 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3371 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3372 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3373 decoderinstances->nNumOfInstances = 16;
3374 /*TODO: How to handle this case */
3375 break;
3376 }
3377 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3378 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3379 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3380 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3381 h264_parser->get_frame_pack_data(configFmt);
3382 } else {
3383 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3384 }
3385 break;
3386 }
3387 case OMX_IndexConfigCommonOutputCrop: {
3388 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3389 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3390 break;
3391 }
3392 default: {
3393 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3394 eRet = OMX_ErrorBadParameter;
3395 }
3396
Shalaj Jain273b3e02012-06-22 19:08:03 -07003397 }
Arun Menon906de572013-06-18 17:01:40 -07003398
3399 return eRet;
3400}
3401
3402/* ======================================================================
3403 FUNCTION
3404 omx_vdec::SetConfig
3405
3406 DESCRIPTION
3407 OMX Set Config method implementation
3408
3409 PARAMETERS
3410 <TBD>.
3411
3412 RETURN VALUE
3413 OMX Error None if successful.
3414 ========================================================================== */
3415OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3416 OMX_IN OMX_INDEXTYPE configIndex,
3417 OMX_IN OMX_PTR configData)
3418{
3419 if (m_state == OMX_StateInvalid) {
3420 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3421 return OMX_ErrorInvalidState;
3422 }
3423
3424 OMX_ERRORTYPE ret = OMX_ErrorNone;
3425 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3426
3427 DEBUG_PRINT_LOW("\n Set Config Called");
3428
3429 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3430 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3431 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3432 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
3433 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3434 OMX_U32 extra_size;
3435 // Parsing done here for the AVC atom is definitely not generic
3436 // Currently this piece of code is working, but certainly
3437 // not tested with all .mp4 files.
3438 // Incase of failure, we might need to revisit this
3439 // for a generic piece of code.
3440
3441 // Retrieve size of NAL length field
3442 // byte #4 contains the size of NAL lenght field
3443 nal_length = (config->pData[4] & 0x03) + 1;
3444
3445 extra_size = 0;
3446 if (nal_length > 2) {
3447 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3448 extra_size = (nal_length - 2) * 2;
3449 }
3450
3451 // SPS starts from byte #6
3452 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3453 OMX_U8 *pDestBuf;
3454 m_vendor_config.nPortIndex = config->nPortIndex;
3455
3456 // minus 6 --> SPS starts from byte #6
3457 // minus 1 --> picture param set byte to be ignored from avcatom
3458 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3459 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3460 OMX_U32 len;
3461 OMX_U8 index = 0;
3462 // case where SPS+PPS is sent as part of set_config
3463 pDestBuf = m_vendor_config.pData;
3464
3465 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
3466 m_vendor_config.nPortIndex,
3467 m_vendor_config.nDataSize,
3468 m_vendor_config.pData);
3469 while (index < 2) {
3470 uint8 *psize;
3471 len = *pSrcBuf;
3472 len = len << 8;
3473 len |= *(pSrcBuf + 1);
3474 psize = (uint8 *) & len;
3475 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3476 for (unsigned int i = 0; i < nal_length; i++) {
3477 pDestBuf[i] = psize[nal_length - 1 - i];
3478 }
3479 //memcpy(pDestBuf,pSrcBuf,(len+2));
3480 pDestBuf += len + nal_length;
3481 pSrcBuf += len + 2;
3482 index++;
3483 pSrcBuf++; // skip picture param set
3484 len = 0;
3485 }
3486 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3487 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3488 m_vendor_config.nPortIndex = config->nPortIndex;
3489 m_vendor_config.nDataSize = config->nDataSize;
3490 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3491 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3492 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3493 if (m_vendor_config.pData) {
3494 free(m_vendor_config.pData);
3495 m_vendor_config.pData = NULL;
3496 m_vendor_config.nDataSize = 0;
3497 }
3498
3499 if (((*((OMX_U32 *) config->pData)) &
3500 VC1_SP_MP_START_CODE_MASK) ==
3501 VC1_SP_MP_START_CODE) {
3502 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3503 m_vendor_config.nPortIndex = config->nPortIndex;
3504 m_vendor_config.nDataSize = config->nDataSize;
3505 m_vendor_config.pData =
3506 (OMX_U8 *) malloc(config->nDataSize);
3507 memcpy(m_vendor_config.pData, config->pData,
3508 config->nDataSize);
3509 m_vc1_profile = VC1_SP_MP_RCV;
3510 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
3511 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3512 m_vendor_config.nPortIndex = config->nPortIndex;
3513 m_vendor_config.nDataSize = config->nDataSize;
3514 m_vendor_config.pData =
3515 (OMX_U8 *) malloc((config->nDataSize));
3516 memcpy(m_vendor_config.pData, config->pData,
3517 config->nDataSize);
3518 m_vc1_profile = VC1_AP;
3519 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
3520 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3521 m_vendor_config.nPortIndex = config->nPortIndex;
3522 m_vendor_config.nDataSize = config->nDataSize;
3523 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3524 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3525 m_vc1_profile = VC1_SP_MP_RCV;
3526 } else {
3527 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3528 }
3529 }
3530 return ret;
3531 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3532 struct v4l2_control temp;
3533 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3534
3535 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3536 switch (pNal->nNaluBytes) {
3537 case 0:
3538 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3539 break;
3540 case 2:
3541 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3542 break;
3543 case 4:
3544 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3545 break;
3546 default:
3547 return OMX_ErrorUnsupportedSetting;
3548 }
3549
3550 if (!arbitrary_bytes) {
3551 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3552 * with start code, so only need to notify driver in frame by frame mode */
3553 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3554 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3555 return OMX_ErrorHardware;
3556 }
3557 }
3558
3559 nal_length = pNal->nNaluBytes;
3560 m_frame_parser.init_nal_length(nal_length);
3561
3562 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
3563 return ret;
3564 } else if (configIndex == OMX_IndexVendorVideoFrameRate) {
3565 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
3566 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps);
3567
3568 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3569 if (config->bEnabled) {
3570 if ((config->nFps >> 16) > 0) {
3571 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d",
3572 config->nFps >> 16);
3573 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3574 drv_ctx.frame_rate.fps_denominator);
3575
3576 if (!drv_ctx.frame_rate.fps_numerator) {
3577 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3578 drv_ctx.frame_rate.fps_numerator = 30;
3579 }
3580
3581 if (drv_ctx.frame_rate.fps_denominator) {
3582 drv_ctx.frame_rate.fps_numerator = (int)
3583 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3584 }
3585
3586 drv_ctx.frame_rate.fps_denominator = 1;
3587 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3588 drv_ctx.frame_rate.fps_numerator;
3589
3590 struct v4l2_outputparm oparm;
3591 /*XXX: we're providing timing info as seconds per frame rather than frames
3592 * per second.*/
3593 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3594 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3595
3596 struct v4l2_streamparm sparm;
3597 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3598 sparm.parm.output = oparm;
3599 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3600 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3601 performance might be affected");
3602 ret = OMX_ErrorHardware;
3603 }
3604 client_set_fps = true;
3605 } else {
3606 DEBUG_PRINT_ERROR("Frame rate not supported.");
3607 ret = OMX_ErrorUnsupportedSetting;
3608 }
3609 } else {
3610 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3611 client_set_fps = false;
3612 }
3613 } else {
3614 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3615 (int)config->nPortIndex);
3616 ret = OMX_ErrorBadPortIndex;
3617 }
3618
3619 return ret;
3620 }
3621
3622 return OMX_ErrorNotImplemented;
3623}
3624
3625/* ======================================================================
3626 FUNCTION
3627 omx_vdec::GetExtensionIndex
3628
3629 DESCRIPTION
3630 OMX GetExtensionIndex method implementaion. <TBD>
3631
3632 PARAMETERS
3633 <TBD>.
3634
3635 RETURN VALUE
3636 OMX Error None if everything successful.
3637
3638 ========================================================================== */
3639OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3640 OMX_IN OMX_STRING paramName,
3641 OMX_OUT OMX_INDEXTYPE* indexType)
3642{
3643 if (m_state == OMX_StateInvalid) {
3644 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3645 return OMX_ErrorInvalidState;
3646 } else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3647 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3648 } else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003649 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3650 }
3651#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003652 else if (!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003653 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Arun Menon906de572013-06-18 17:01:40 -07003654 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003655 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Arun Menon906de572013-06-18 17:01:40 -07003656 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003657 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3658 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Arun Menon906de572013-06-18 17:01:40 -07003659 } else if (!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003660 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3661 }
3662#endif
Arun Menon906de572013-06-18 17:01:40 -07003663 else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003664 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3665 return OMX_ErrorNotImplemented;
3666 }
3667 return OMX_ErrorNone;
3668}
3669
3670/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003671 FUNCTION
3672 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07003673
Arun Menon906de572013-06-18 17:01:40 -07003674 DESCRIPTION
3675 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003676
Arun Menon906de572013-06-18 17:01:40 -07003677 PARAMETERS
3678 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003679
Arun Menon906de572013-06-18 17:01:40 -07003680 RETURN VALUE
3681 Error None if everything is successful.
3682 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003683OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003684 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003685{
Arun Menon906de572013-06-18 17:01:40 -07003686 *state = m_state;
3687 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
3688 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003689}
3690
3691/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003692 FUNCTION
3693 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07003694
Arun Menon906de572013-06-18 17:01:40 -07003695 DESCRIPTION
3696 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003697
Arun Menon906de572013-06-18 17:01:40 -07003698 PARAMETERS
3699 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003700
Arun Menon906de572013-06-18 17:01:40 -07003701 RETURN VALUE
3702 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003703
Arun Menon906de572013-06-18 17:01:40 -07003704 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003705OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003706 OMX_IN OMX_U32 port,
3707 OMX_IN OMX_HANDLETYPE peerComponent,
3708 OMX_IN OMX_U32 peerPort,
3709 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003710{
Arun Menon906de572013-06-18 17:01:40 -07003711 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3712 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003713}
3714
3715/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003716 FUNCTION
3717 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07003718
Arun Menon906de572013-06-18 17:01:40 -07003719 DESCRIPTION
3720 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07003721
Arun Menon906de572013-06-18 17:01:40 -07003722 PARAMETERS
3723 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003724
Arun Menon906de572013-06-18 17:01:40 -07003725 RETURN VALUE
3726 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07003727
Arun Menon906de572013-06-18 17:01:40 -07003728 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003729OMX_ERRORTYPE omx_vdec::allocate_extradata()
3730{
3731#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003732 if (drv_ctx.extradata_info.buffer_size) {
3733 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
3734 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3735 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3736 free_ion_memory(&drv_ctx.extradata_info.ion);
3737 }
3738 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
3739 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
3740 drv_ctx.extradata_info.size, 4096,
3741 &drv_ctx.extradata_info.ion.ion_alloc_data,
3742 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
3743 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
3744 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
3745 return OMX_ErrorInsufficientResources;
3746 }
3747 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
3748 drv_ctx.extradata_info.size,
3749 PROT_READ|PROT_WRITE, MAP_SHARED,
3750 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
3751 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
3752 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
3753 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3754 free_ion_memory(&drv_ctx.extradata_info.ion);
3755 return OMX_ErrorInsufficientResources;
3756 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003757 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003758#endif
Arun Menon906de572013-06-18 17:01:40 -07003759 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003760}
3761
Arun Menon906de572013-06-18 17:01:40 -07003762void omx_vdec::free_extradata()
3763{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003764#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003765 if (drv_ctx.extradata_info.uaddr) {
3766 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3767 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3768 free_ion_memory(&drv_ctx.extradata_info.ion);
3769 }
3770 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003771#endif
3772}
3773
Shalaj Jain273b3e02012-06-22 19:08:03 -07003774OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07003775 OMX_IN OMX_HANDLETYPE hComp,
3776 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3777 OMX_IN OMX_U32 port,
3778 OMX_IN OMX_PTR appData,
3779 OMX_IN OMX_U32 bytes,
3780 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003781{
Arun Menon906de572013-06-18 17:01:40 -07003782 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3783 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
3784 unsigned i= 0; // Temporary counter
3785 struct vdec_setbuffer_cmd setbuffers;
3786 OMX_PTR privateAppData = NULL;
3787 private_handle_t *handle = NULL;
3788 OMX_U8 *buff = buffer;
3789 struct v4l2_buffer buf;
3790 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3791 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003792
Arun Menon906de572013-06-18 17:01:40 -07003793 if (!m_out_mem_ptr) {
3794 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
3795 eRet = allocate_output_headers();
3796 if (eRet == OMX_ErrorNone)
3797 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07003798 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003799
Arun Menon906de572013-06-18 17:01:40 -07003800 if (eRet == OMX_ErrorNone) {
3801 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
3802 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
3803 break;
3804 }
3805 }
3806 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003807
Arun Menon906de572013-06-18 17:01:40 -07003808 if (i >= drv_ctx.op_buf.actualcount) {
3809 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
3810 eRet = OMX_ErrorInsufficientResources;
3811 }
3812
3813 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003814#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003815 if (m_enable_android_native_buffers) {
3816 if (m_use_android_native_buffers) {
3817 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
3818 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3819 handle = (private_handle_t *)nBuf->handle;
3820 privateAppData = params->pAppPrivate;
3821 } else {
3822 handle = (private_handle_t *)buff;
3823 privateAppData = appData;
3824 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003825
Arun Menon906de572013-06-18 17:01:40 -07003826 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
3827 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
3828 " expected %u, got %lu",
3829 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
3830 return OMX_ErrorBadParameter;
3831 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003832
Arun Menon906de572013-06-18 17:01:40 -07003833 if (!m_use_android_native_buffers) {
3834 if (!secure_mode) {
3835 buff = (OMX_U8*)mmap(0, handle->size,
3836 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3837 if (buff == MAP_FAILED) {
3838 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3839 return OMX_ErrorInsufficientResources;
3840 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003841 }
3842 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003843#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003844 native_buffer[i].nativehandle = handle;
3845 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003846#endif
Arun Menon906de572013-06-18 17:01:40 -07003847 if (!handle) {
3848 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
3849 return OMX_ErrorBadParameter;
3850 }
3851 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
3852 drv_ctx.ptr_outputbuffer[i].offset = 0;
3853 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
3854 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
3855 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
3856 } else
3857#endif
3858
3859 if (!ouput_egl_buffers && !m_use_output_pmem) {
3860#ifdef USE_ION
3861 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
3862 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
3863 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
3864 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
3865 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
3866 DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd);
3867 return OMX_ErrorInsufficientResources;
3868 }
3869 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3870 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
3871#else
3872 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3873 open (MEM_DEVICE,O_RDWR);
3874
3875 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
3876 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
3877 return OMX_ErrorInsufficientResources;
3878 }
3879
3880 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
3881 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
3882 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3883 open (MEM_DEVICE,O_RDWR);
3884 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
3885 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
3886 return OMX_ErrorInsufficientResources;
3887 }
3888 }
3889
3890 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
3891 drv_ctx.op_buf.buffer_size,
3892 drv_ctx.op_buf.alignment)) {
3893 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3894 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
3895 return OMX_ErrorInsufficientResources;
3896 }
3897#endif
3898 if (!secure_mode) {
3899 drv_ctx.ptr_outputbuffer[i].bufferaddr =
3900 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
3901 PROT_READ|PROT_WRITE, MAP_SHARED,
3902 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
3903 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
3904 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
3905#ifdef USE_ION
3906 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
3907#endif
3908 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
3909 return OMX_ErrorInsufficientResources;
3910 }
3911 }
3912 drv_ctx.ptr_outputbuffer[i].offset = 0;
3913 privateAppData = appData;
3914 } else {
3915
3916 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
3917 if (!appData || !bytes ) {
3918 if (!secure_mode && !buffer) {
3919 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
3920 return OMX_ErrorBadParameter;
3921 }
3922 }
3923
3924 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
3925 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
3926 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
3927 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
3928 !pmem_list->nEntries ||
3929 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3930 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
3931 return OMX_ErrorBadParameter;
3932 }
3933 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
3934 pmem_list->entryList->entry;
3935 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
3936 pmem_info->pmem_fd);
3937 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
3938 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
3939 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
3940 drv_ctx.ptr_outputbuffer[i].mmaped_size =
3941 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
3942 privateAppData = appData;
3943 }
3944 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
3945 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
3946
3947 *bufferHdr = (m_out_mem_ptr + i );
3948 if (secure_mode)
3949 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
3950 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
3951 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
3952 sizeof (vdec_bufferpayload));
3953
3954 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
3955 drv_ctx.ptr_outputbuffer[i].bufferaddr,
3956 drv_ctx.ptr_outputbuffer[i].pmem_fd );
3957
3958 buf.index = i;
3959 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3960 buf.memory = V4L2_MEMORY_USERPTR;
3961 plane[0].length = drv_ctx.op_buf.buffer_size;
3962 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
3963 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
3964 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
3965 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
3966 plane[0].data_offset = 0;
3967 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
3968 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3969 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
3970 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
3971#ifdef USE_ION
3972 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
3973#endif
3974 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
3975 plane[extra_idx].data_offset = 0;
3976 } else if (extra_idx >= VIDEO_MAX_PLANES) {
3977 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003978 return OMX_ErrorBadParameter;
3979 }
Arun Menon906de572013-06-18 17:01:40 -07003980 buf.m.planes = plane;
3981 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003982
Arun Menon906de572013-06-18 17:01:40 -07003983 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
3984 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
3985 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003986 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003987 }
3988
Arun Menon906de572013-06-18 17:01:40 -07003989 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
3990 enum v4l2_buf_type buf_type;
3991 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3992 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
3993 return OMX_ErrorInsufficientResources;
3994 } else {
3995 streaming[CAPTURE_PORT] = true;
3996 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003997 }
3998 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003999
Arun Menon906de572013-06-18 17:01:40 -07004000 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4001 if (m_enable_android_native_buffers) {
4002 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4003 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4004 } else {
4005 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004006 }
Arun Menon906de572013-06-18 17:01:40 -07004007 (*bufferHdr)->pAppPrivate = privateAppData;
4008 BITMASK_SET(&m_out_bm_count,i);
4009 }
4010 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004011}
4012
4013/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004014 FUNCTION
4015 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004016
Arun Menon906de572013-06-18 17:01:40 -07004017 DESCRIPTION
4018 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004019
Arun Menon906de572013-06-18 17:01:40 -07004020 PARAMETERS
4021 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004022
Arun Menon906de572013-06-18 17:01:40 -07004023 RETURN VALUE
4024 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004025
Arun Menon906de572013-06-18 17:01:40 -07004026 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004027OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004028 OMX_IN OMX_HANDLETYPE hComp,
4029 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4030 OMX_IN OMX_U32 port,
4031 OMX_IN OMX_PTR appData,
4032 OMX_IN OMX_U32 bytes,
4033 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004034{
Arun Menon906de572013-06-18 17:01:40 -07004035 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4036 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4037 if (!m_inp_heap_ptr)
4038 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4039 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4040 drv_ctx.ip_buf.actualcount);
4041 if (!m_phdr_pmem_ptr)
4042 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4043 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4044 drv_ctx.ip_buf.actualcount);
4045 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4046 DEBUG_PRINT_ERROR("Insufficent memory");
4047 eRet = OMX_ErrorInsufficientResources;
4048 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4049 input_use_buffer = true;
4050 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4051 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4052 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4053 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4054 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4055 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4056 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4057 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4058 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
4059 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4060 (unsigned)NULL, (unsigned)NULL)) {
4061 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4062 return OMX_ErrorInsufficientResources;
4063 }
4064 m_in_alloc_cnt++;
4065 } else {
4066 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4067 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004068 }
Arun Menon906de572013-06-18 17:01:40 -07004069 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004070}
4071
4072/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004073 FUNCTION
4074 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004075
Arun Menon906de572013-06-18 17:01:40 -07004076 DESCRIPTION
4077 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004078
Arun Menon906de572013-06-18 17:01:40 -07004079 PARAMETERS
4080 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004081
Arun Menon906de572013-06-18 17:01:40 -07004082 RETURN VALUE
4083 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004084
Arun Menon906de572013-06-18 17:01:40 -07004085 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004086OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004087 OMX_IN OMX_HANDLETYPE hComp,
4088 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4089 OMX_IN OMX_U32 port,
4090 OMX_IN OMX_PTR appData,
4091 OMX_IN OMX_U32 bytes,
4092 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004093{
Arun Menon906de572013-06-18 17:01:40 -07004094 OMX_ERRORTYPE error = OMX_ErrorNone;
4095 struct vdec_setbuffer_cmd setbuffers;
4096
4097 if (bufferHdr == NULL || bytes == 0) {
4098 if (!secure_mode && buffer == NULL) {
4099 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4100 return OMX_ErrorBadParameter;
4101 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004102 }
Arun Menon906de572013-06-18 17:01:40 -07004103 if (m_state == OMX_StateInvalid) {
4104 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4105 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004106 }
Arun Menon906de572013-06-18 17:01:40 -07004107 if (port == OMX_CORE_INPUT_PORT_INDEX)
4108 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4109 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4110 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4111 else {
4112 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4113 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004114 }
Arun Menon906de572013-06-18 17:01:40 -07004115 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4116 if (error == OMX_ErrorNone) {
4117 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4118 // Send the callback now
4119 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4120 post_event(OMX_CommandStateSet,OMX_StateIdle,
4121 OMX_COMPONENT_GENERATE_EVENT);
4122 }
4123 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4124 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4125 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4126 post_event(OMX_CommandPortEnable,
4127 OMX_CORE_INPUT_PORT_INDEX,
4128 OMX_COMPONENT_GENERATE_EVENT);
4129 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4130 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4131 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4132 post_event(OMX_CommandPortEnable,
4133 OMX_CORE_OUTPUT_PORT_INDEX,
4134 OMX_COMPONENT_GENERATE_EVENT);
4135 }
4136 }
4137 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004138}
4139
4140OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004141 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004142{
Arun Menon906de572013-06-18 17:01:40 -07004143 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4144 if (m_inp_heap_ptr[bufferindex].pBuffer)
4145 free(m_inp_heap_ptr[bufferindex].pBuffer);
4146 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4147 }
4148 if (pmem_bufferHdr)
4149 free_input_buffer(pmem_bufferHdr);
4150 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004151}
4152
4153OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4154{
Arun Menon906de572013-06-18 17:01:40 -07004155 unsigned int index = 0;
4156 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4157 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004158 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004159
Arun Menon906de572013-06-18 17:01:40 -07004160 index = bufferHdr - m_inp_mem_ptr;
4161 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4162
4163 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
4164 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4165 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4166 struct vdec_setbuffer_cmd setbuffers;
4167 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4168 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4169 sizeof (vdec_bufferpayload));
4170 if (!secure_mode) {
4171 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4172 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4173 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4174 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4175 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4176 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4177 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4178 }
4179 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4180 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4181 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4182 free(m_desc_buffer_ptr[index].buf_addr);
4183 m_desc_buffer_ptr[index].buf_addr = NULL;
4184 m_desc_buffer_ptr[index].desc_data_size = 0;
4185 }
4186#ifdef USE_ION
4187 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4188#endif
4189 }
4190 }
4191
4192 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004193}
4194
4195OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4196{
Arun Menon906de572013-06-18 17:01:40 -07004197 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004198
Arun Menon906de572013-06-18 17:01:40 -07004199 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4200 return OMX_ErrorBadParameter;
4201 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004202
Arun Menon906de572013-06-18 17:01:40 -07004203 index = bufferHdr - m_out_mem_ptr;
4204 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004205
Arun Menon906de572013-06-18 17:01:40 -07004206 if (index < drv_ctx.op_buf.actualcount
4207 && drv_ctx.ptr_outputbuffer) {
4208 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
4209 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004210
Arun Menon906de572013-06-18 17:01:40 -07004211 struct vdec_setbuffer_cmd setbuffers;
4212 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4213 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4214 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004215#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004216 if (m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004217 if (!secure_mode) {
Arun Menon906de572013-06-18 17:01:40 -07004218 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4219 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4220 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4221 }
Praveen Chavan212671f2013-04-05 20:00:42 -07004222 }
Arun Menon906de572013-06-18 17:01:40 -07004223 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4224 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004225#endif
Arun Menon906de572013-06-18 17:01:40 -07004226 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4227 if (!secure_mode) {
4228 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4229 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4230 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4231 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4232 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4233 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4234 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4235 }
4236 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4237 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004238#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004239 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004240#endif
Arun Menon906de572013-06-18 17:01:40 -07004241 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004242#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004243 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004244#endif
Arun Menon906de572013-06-18 17:01:40 -07004245 if (release_output_done()) {
4246 free_extradata();
4247 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004248 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004249
Arun Menon906de572013-06-18 17:01:40 -07004250 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004251
4252}
4253
4254OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004255 OMX_BUFFERHEADERTYPE **bufferHdr,
4256 OMX_U32 port,
4257 OMX_PTR appData,
4258 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004259{
Arun Menon906de572013-06-18 17:01:40 -07004260 OMX_BUFFERHEADERTYPE *input = NULL;
4261 unsigned char *buf_addr = NULL;
4262 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4263 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004264
Arun Menon906de572013-06-18 17:01:40 -07004265 /* Sanity Check*/
4266 if (bufferHdr == NULL) {
4267 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004268 }
4269
Arun Menon906de572013-06-18 17:01:40 -07004270 if (m_inp_heap_ptr == NULL) {
4271 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4272 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4273 drv_ctx.ip_buf.actualcount);
4274 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4275 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4276 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004277
Arun Menon906de572013-06-18 17:01:40 -07004278 if (m_inp_heap_ptr == NULL) {
4279 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4280 return OMX_ErrorInsufficientResources;
4281 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004282 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004283
Arun Menon906de572013-06-18 17:01:40 -07004284 /*Find a Free index*/
4285 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4286 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
4287 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4288 break;
4289 }
4290 }
4291
4292 if (i < drv_ctx.ip_buf.actualcount) {
4293 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4294
4295 if (buf_addr == NULL) {
4296 return OMX_ErrorInsufficientResources;
4297 }
4298
4299 *bufferHdr = (m_inp_heap_ptr + i);
4300 input = *bufferHdr;
4301 BITMASK_SET(&m_heap_inp_bm_count,i);
4302
4303 input->pBuffer = (OMX_U8 *)buf_addr;
4304 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4305 input->nVersion.nVersion = OMX_SPEC_VERSION;
4306 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4307 input->pAppPrivate = appData;
4308 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4309 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4310 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4311 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
4312 /*Add the Buffers to freeq*/
4313 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4314 (unsigned)NULL, (unsigned)NULL)) {
4315 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4316 return OMX_ErrorInsufficientResources;
4317 }
4318 } else {
4319 return OMX_ErrorBadParameter;
4320 }
4321
4322 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004323
4324}
4325
4326
4327/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004328 FUNCTION
4329 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004330
Arun Menon906de572013-06-18 17:01:40 -07004331 DESCRIPTION
4332 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004333
Arun Menon906de572013-06-18 17:01:40 -07004334 PARAMETERS
4335 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004336
Arun Menon906de572013-06-18 17:01:40 -07004337 RETURN VALUE
4338 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004339
Arun Menon906de572013-06-18 17:01:40 -07004340 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004341OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004342 OMX_IN OMX_HANDLETYPE hComp,
4343 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4344 OMX_IN OMX_U32 port,
4345 OMX_IN OMX_PTR appData,
4346 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004347{
4348
Arun Menon906de572013-06-18 17:01:40 -07004349 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4350 struct vdec_setbuffer_cmd setbuffers;
4351 OMX_BUFFERHEADERTYPE *input = NULL;
4352 unsigned i = 0;
4353 unsigned char *buf_addr = NULL;
4354 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004355
Arun Menon906de572013-06-18 17:01:40 -07004356 if (bytes != drv_ctx.ip_buf.buffer_size) {
4357 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
4358 bytes, drv_ctx.ip_buf.buffer_size);
4359 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004360 }
4361
Arun Menon906de572013-06-18 17:01:40 -07004362 if (!m_inp_mem_ptr) {
4363 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4364 drv_ctx.ip_buf.actualcount,
4365 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004366
Arun Menon906de572013-06-18 17:01:40 -07004367 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4368 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4369
4370 if (m_inp_mem_ptr == NULL) {
4371 return OMX_ErrorInsufficientResources;
4372 }
4373
4374 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4375 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4376
4377 if (drv_ctx.ptr_inputbuffer == NULL) {
4378 return OMX_ErrorInsufficientResources;
4379 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004380#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004381 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4382 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004383
Arun Menon906de572013-06-18 17:01:40 -07004384 if (drv_ctx.ip_buf_ion_info == NULL) {
4385 return OMX_ErrorInsufficientResources;
4386 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004387#endif
4388
Arun Menon906de572013-06-18 17:01:40 -07004389 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4390 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004391#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004392 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004393#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004394 }
4395 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004396
Arun Menon906de572013-06-18 17:01:40 -07004397 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4398 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4399 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4400 break;
4401 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004402 }
Arun Menon906de572013-06-18 17:01:40 -07004403
4404 if (i < drv_ctx.ip_buf.actualcount) {
4405 struct v4l2_buffer buf;
4406 struct v4l2_plane plane;
4407 int rc;
4408 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4409#ifdef USE_ION
4410 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4411 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4412 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4413 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4414 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4415 return OMX_ErrorInsufficientResources;
4416 }
4417 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4418#else
4419 pmem_fd = open (MEM_DEVICE,O_RDWR);
4420
4421 if (pmem_fd < 0) {
4422 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4423 return OMX_ErrorInsufficientResources;
4424 }
4425
4426 if (pmem_fd == 0) {
4427 pmem_fd = open (MEM_DEVICE,O_RDWR);
4428
4429 if (pmem_fd < 0) {
4430 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4431 return OMX_ErrorInsufficientResources;
4432 }
4433 }
4434
4435 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4436 drv_ctx.ip_buf.alignment)) {
4437 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4438 close(pmem_fd);
4439 return OMX_ErrorInsufficientResources;
4440 }
4441#endif
4442 if (!secure_mode) {
4443 buf_addr = (unsigned char *)mmap(NULL,
4444 drv_ctx.ip_buf.buffer_size,
4445 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4446
4447 if (buf_addr == MAP_FAILED) {
4448 close(pmem_fd);
4449#ifdef USE_ION
4450 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4451#endif
4452 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4453 return OMX_ErrorInsufficientResources;
4454 }
4455 }
4456 *bufferHdr = (m_inp_mem_ptr + i);
4457 if (secure_mode)
4458 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4459 else
4460 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4461 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4462 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4463 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4464 drv_ctx.ptr_inputbuffer [i].offset = 0;
4465
4466
4467 buf.index = i;
4468 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4469 buf.memory = V4L2_MEMORY_USERPTR;
4470 plane.bytesused = 0;
4471 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4472 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4473 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4474 plane.reserved[1] = 0;
4475 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4476 buf.m.planes = &plane;
4477 buf.length = 1;
4478
4479 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4480 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4481
4482 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4483
4484 if (rc) {
4485 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4486 /*TODO: How to handle this case */
4487 return OMX_ErrorInsufficientResources;
4488 }
4489
4490 input = *bufferHdr;
4491 BITMASK_SET(&m_inp_bm_count,i);
4492 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4493 if (secure_mode)
4494 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4495 else
4496 input->pBuffer = (OMX_U8 *)buf_addr;
4497 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4498 input->nVersion.nVersion = OMX_SPEC_VERSION;
4499 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4500 input->pAppPrivate = appData;
4501 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4502 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4503
4504 if (drv_ctx.disable_dmx) {
4505 eRet = allocate_desc_buffer(i);
4506 }
4507 } else {
4508 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4509 eRet = OMX_ErrorInsufficientResources;
4510 }
4511 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004512}
4513
4514
4515/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004516 FUNCTION
4517 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004518
Arun Menon906de572013-06-18 17:01:40 -07004519 DESCRIPTION
4520 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004521
Arun Menon906de572013-06-18 17:01:40 -07004522 PARAMETERS
4523 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004524
Arun Menon906de572013-06-18 17:01:40 -07004525 RETURN VALUE
4526 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004527
Arun Menon906de572013-06-18 17:01:40 -07004528 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004529OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004530 OMX_IN OMX_HANDLETYPE hComp,
4531 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4532 OMX_IN OMX_U32 port,
4533 OMX_IN OMX_PTR appData,
4534 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004535{
Arun Menon906de572013-06-18 17:01:40 -07004536 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4537 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4538 unsigned i= 0; // Temporary counter
4539 struct vdec_setbuffer_cmd setbuffers;
4540 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004541#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004542 int ion_device_fd =-1;
4543 struct ion_allocation_data ion_alloc_data;
4544 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004545#endif
Arun Menon906de572013-06-18 17:01:40 -07004546 if (!m_out_mem_ptr) {
4547 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4548 drv_ctx.op_buf.actualcount,
4549 drv_ctx.op_buf.buffer_size);
4550 int nBufHdrSize = 0;
4551 int nPlatformEntrySize = 0;
4552 int nPlatformListSize = 0;
4553 int nPMEMInfoSize = 0;
4554 int pmem_fd = -1;
4555 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004556
Arun Menon906de572013-06-18 17:01:40 -07004557 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4558 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4559 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004560
Arun Menon906de572013-06-18 17:01:40 -07004561 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4562 drv_ctx.op_buf.actualcount);
4563 nBufHdrSize = drv_ctx.op_buf.actualcount *
4564 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004565
Arun Menon906de572013-06-18 17:01:40 -07004566 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4567 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4568 nPlatformListSize = drv_ctx.op_buf.actualcount *
4569 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4570 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4571 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004572
Arun Menon906de572013-06-18 17:01:40 -07004573 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4574 sizeof(OMX_BUFFERHEADERTYPE),
4575 nPMEMInfoSize,
4576 nPlatformListSize);
4577 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4578 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004579#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004580 ion_device_fd = alloc_map_ion_memory(
4581 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4582 drv_ctx.op_buf.alignment,
4583 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4584 if (ion_device_fd < 0) {
4585 return OMX_ErrorInsufficientResources;
4586 }
4587 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004588#else
Arun Menon906de572013-06-18 17:01:40 -07004589 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004590
Arun Menon906de572013-06-18 17:01:40 -07004591 if (pmem_fd < 0) {
4592 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4593 drv_ctx.op_buf.buffer_size);
4594 return OMX_ErrorInsufficientResources;
4595 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004596
Arun Menon906de572013-06-18 17:01:40 -07004597 if (pmem_fd == 0) {
4598 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004599
Arun Menon906de572013-06-18 17:01:40 -07004600 if (pmem_fd < 0) {
4601 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4602 drv_ctx.op_buf.buffer_size);
4603 return OMX_ErrorInsufficientResources;
4604 }
4605 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004606
Arun Menon906de572013-06-18 17:01:40 -07004607 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4608 drv_ctx.op_buf.actualcount,
4609 drv_ctx.op_buf.alignment)) {
4610 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4611 close(pmem_fd);
4612 return OMX_ErrorInsufficientResources;
4613 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004614#endif
Arun Menon906de572013-06-18 17:01:40 -07004615 if (!secure_mode) {
4616 pmem_baseaddress = (unsigned char *)mmap(NULL,
4617 (drv_ctx.op_buf.buffer_size *
4618 drv_ctx.op_buf.actualcount),
4619 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4620 if (pmem_baseaddress == MAP_FAILED) {
4621 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4622 drv_ctx.op_buf.buffer_size);
4623 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004624#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004625 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004626#endif
Arun Menon906de572013-06-18 17:01:40 -07004627 return OMX_ErrorInsufficientResources;
4628 }
4629 }
4630 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4631 // Alloc mem for platform specific info
4632 char *pPtr=NULL;
4633 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4634 nPMEMInfoSize,1);
4635 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4636 calloc (sizeof(struct vdec_bufferpayload),
4637 drv_ctx.op_buf.actualcount);
4638 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4639 calloc (sizeof (struct vdec_output_frameinfo),
4640 drv_ctx.op_buf.actualcount);
4641#ifdef USE_ION
4642 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4643 calloc (sizeof(struct vdec_ion),
4644 drv_ctx.op_buf.actualcount);
4645#endif
4646
4647 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4648 && drv_ctx.ptr_respbuffer) {
4649 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4650 (drv_ctx.op_buf.buffer_size *
4651 drv_ctx.op_buf.actualcount);
4652 bufHdr = m_out_mem_ptr;
4653 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4654 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4655 (((char *) m_platform_list) + nPlatformListSize);
4656 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4657 (((char *) m_platform_entry) + nPlatformEntrySize);
4658 pPlatformList = m_platform_list;
4659 pPlatformEntry = m_platform_entry;
4660 pPMEMInfo = m_pmem_info;
4661
4662 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
4663
4664 // Settting the entire storage nicely
4665 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
4666 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
4667 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4668 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4669 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4670 // Set the values when we determine the right HxW param
4671 bufHdr->nAllocLen = bytes;
4672 bufHdr->nFilledLen = 0;
4673 bufHdr->pAppPrivate = appData;
4674 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4675 // Platform specific PMEM Information
4676 // Initialize the Platform Entry
4677 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
4678 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4679 pPlatformEntry->entry = pPMEMInfo;
4680 // Initialize the Platform List
4681 pPlatformList->nEntries = 1;
4682 pPlatformList->entryList = pPlatformEntry;
4683 // Keep pBuffer NULL till vdec is opened
4684 bufHdr->pBuffer = NULL;
4685 bufHdr->nOffset = 0;
4686
4687 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4688 pPMEMInfo->pmem_fd = 0;
4689 bufHdr->pPlatformPrivate = pPlatformList;
4690
4691 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
4692 m_pmem_info[i].pmem_fd = pmem_fd;
4693#ifdef USE_ION
4694 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
4695 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
4696 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
4697#endif
4698
4699 /*Create a mapping between buffers*/
4700 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
4701 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
4702 &drv_ctx.ptr_outputbuffer[i];
4703 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
4704 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4705 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
4706
4707 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
4708 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
4709 drv_ctx.ptr_outputbuffer[i].bufferaddr);
4710 // Move the buffer and buffer header pointers
4711 bufHdr++;
4712 pPMEMInfo++;
4713 pPlatformEntry++;
4714 pPlatformList++;
4715 }
4716 } else {
4717 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
4718 m_out_mem_ptr, pPtr);
4719 if (m_out_mem_ptr) {
4720 free(m_out_mem_ptr);
4721 m_out_mem_ptr = NULL;
4722 }
4723 if (pPtr) {
4724 free(pPtr);
4725 pPtr = NULL;
4726 }
4727 if (drv_ctx.ptr_outputbuffer) {
4728 free(drv_ctx.ptr_outputbuffer);
4729 drv_ctx.ptr_outputbuffer = NULL;
4730 }
4731 if (drv_ctx.ptr_respbuffer) {
4732 free(drv_ctx.ptr_respbuffer);
4733 drv_ctx.ptr_respbuffer = NULL;
4734 }
4735#ifdef USE_ION
4736 if (drv_ctx.op_buf_ion_info) {
4737 DEBUG_PRINT_LOW("\n Free o/p ion context");
4738 free(drv_ctx.op_buf_ion_info);
4739 drv_ctx.op_buf_ion_info = NULL;
4740 }
4741#endif
4742 eRet = OMX_ErrorInsufficientResources;
4743 }
4744 if (eRet == OMX_ErrorNone)
4745 eRet = allocate_extradata();
4746 }
4747
4748 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4749 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4750 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
4751 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004752 }
4753 }
Arun Menon906de572013-06-18 17:01:40 -07004754
4755 if (eRet == OMX_ErrorNone) {
4756 if (i < drv_ctx.op_buf.actualcount) {
4757 struct v4l2_buffer buf;
4758 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4759 int rc;
4760 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4761
4762 drv_ctx.ptr_outputbuffer[i].buffer_len =
4763 drv_ctx.op_buf.buffer_size;
4764
4765 *bufferHdr = (m_out_mem_ptr + i );
4766 if (secure_mode) {
4767 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4768 }
4769 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
4770
4771 buf.index = i;
4772 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4773 buf.memory = V4L2_MEMORY_USERPTR;
4774 plane[0].length = drv_ctx.op_buf.buffer_size;
4775 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4776 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004777#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004778 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004779#endif
Arun Menon906de572013-06-18 17:01:40 -07004780 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4781 plane[0].data_offset = 0;
4782 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4783 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4784 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4785 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 -07004786#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004787 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004788#endif
Arun Menon906de572013-06-18 17:01:40 -07004789 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4790 plane[extra_idx].data_offset = 0;
4791 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4792 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
4793 return OMX_ErrorBadParameter;
4794 }
4795 buf.m.planes = plane;
4796 buf.length = drv_ctx.num_planes;
4797 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
4798 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4799 if (rc) {
4800 /*TODO: How to handle this case */
4801 return OMX_ErrorInsufficientResources;
4802 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004803
Arun Menon906de572013-06-18 17:01:40 -07004804 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
4805 enum v4l2_buf_type buf_type;
4806 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4807 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
4808 if (rc) {
4809 return OMX_ErrorInsufficientResources;
4810 } else {
4811 streaming[CAPTURE_PORT] = true;
4812 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4813 }
4814 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004815
Arun Menon906de572013-06-18 17:01:40 -07004816 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
4817 (*bufferHdr)->pAppPrivate = appData;
4818 BITMASK_SET(&m_out_bm_count,i);
4819 } else {
4820 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
4821 eRet = OMX_ErrorInsufficientResources;
4822 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004823 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004824
Arun Menon906de572013-06-18 17:01:40 -07004825 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004826}
4827
4828
4829// AllocateBuffer -- API Call
4830/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004831 FUNCTION
4832 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004833
Arun Menon906de572013-06-18 17:01:40 -07004834 DESCRIPTION
4835 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07004836
Arun Menon906de572013-06-18 17:01:40 -07004837 PARAMETERS
4838 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004839
Arun Menon906de572013-06-18 17:01:40 -07004840 RETURN VALUE
4841 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004842
Arun Menon906de572013-06-18 17:01:40 -07004843 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004844OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004845 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4846 OMX_IN OMX_U32 port,
4847 OMX_IN OMX_PTR appData,
4848 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004849{
4850 unsigned i = 0;
4851 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
4852
4853 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07004854 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004855 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
4856 return OMX_ErrorInvalidState;
4857 }
4858
Arun Menon906de572013-06-18 17:01:40 -07004859 if (port == OMX_CORE_INPUT_PORT_INDEX) {
4860 if (arbitrary_bytes) {
4861 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
4862 } else {
4863 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
4864 }
4865 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08004866 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
4867 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07004868 } else {
4869 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4870 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004871 }
4872 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07004873 if (eRet == OMX_ErrorNone) {
4874 if (allocate_done()) {
4875 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004876 // Send the callback now
4877 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4878 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07004879 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004880 }
4881 }
Arun Menon906de572013-06-18 17:01:40 -07004882 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
4883 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4884 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4885 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004886 OMX_CORE_INPUT_PORT_INDEX,
4887 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07004888 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004889 }
Arun Menon906de572013-06-18 17:01:40 -07004890 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
4891 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4892 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004893 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07004894 OMX_CORE_OUTPUT_PORT_INDEX,
4895 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004896 }
4897 }
4898 }
4899 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
4900 return eRet;
4901}
4902
4903// Free Buffer - API call
4904/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004905 FUNCTION
4906 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004907
Arun Menon906de572013-06-18 17:01:40 -07004908 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07004909
Arun Menon906de572013-06-18 17:01:40 -07004910 PARAMETERS
4911 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004912
Arun Menon906de572013-06-18 17:01:40 -07004913 RETURN VALUE
4914 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004915
Arun Menon906de572013-06-18 17:01:40 -07004916 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004917OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004918 OMX_IN OMX_U32 port,
4919 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004920{
4921 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4922 unsigned int nPortIndex;
4923 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
4924
Arun Menon906de572013-06-18 17:01:40 -07004925 if (m_state == OMX_StateIdle &&
4926 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004927 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
Arun Menon906de572013-06-18 17:01:40 -07004928 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
4929 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07004930 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Arun Menon906de572013-06-18 17:01:40 -07004931 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
4932 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
4933 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
4934 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Arun Menon9f098152013-05-08 13:53:54 -07004935 DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port);
Arun Menon906de572013-06-18 17:01:40 -07004936 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004937 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
4938 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07004939 OMX_ErrorPortUnpopulated,
4940 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004941
4942 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07004943 } else if (m_state != OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004944 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
4945 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07004946 OMX_ErrorPortUnpopulated,
4947 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004948 }
4949
Arun Menon906de572013-06-18 17:01:40 -07004950 if (port == OMX_CORE_INPUT_PORT_INDEX) {
4951 /*Check if arbitrary bytes*/
4952 if (!arbitrary_bytes && !input_use_buffer)
4953 nPortIndex = buffer - m_inp_mem_ptr;
4954 else
4955 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004956
4957 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07004958 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
4959 // Clear the bit associated with it.
4960 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
4961 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
4962 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004963
Arun Menon906de572013-06-18 17:01:40 -07004964 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
4965 if (m_phdr_pmem_ptr)
4966 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
4967 } else {
4968 if (arbitrary_bytes) {
4969 if (m_phdr_pmem_ptr)
4970 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
4971 else
4972 free_input_buffer(nPortIndex,NULL);
4973 } else
4974 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004975 }
Arun Menon906de572013-06-18 17:01:40 -07004976 m_inp_bPopulated = OMX_FALSE;
4977 /*Free the Buffer Header*/
4978 if (release_input_done()) {
4979 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
4980 free_input_buffer_header();
4981 }
4982 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004983 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
4984 eRet = OMX_ErrorBadPortIndex;
4985 }
4986
Arun Menon906de572013-06-18 17:01:40 -07004987 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
4988 && release_input_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004989 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
4990 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
4991 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07004992 OMX_CORE_INPUT_PORT_INDEX,
4993 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004994 }
Arun Menon906de572013-06-18 17:01:40 -07004995 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004996 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08004997 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07004998 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004999 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5000 // Clear the bit associated with it.
5001 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5002 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005003 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005004
Arun Menon906de572013-06-18 17:01:40 -07005005 if (release_output_done()) {
5006 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005007 }
Arun Menon906de572013-06-18 17:01:40 -07005008 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005009 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5010 eRet = OMX_ErrorBadPortIndex;
5011 }
Arun Menon906de572013-06-18 17:01:40 -07005012 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5013 && release_output_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005014 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5015
Arun Menon906de572013-06-18 17:01:40 -07005016 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5017 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005018#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005019 if (m_enable_android_native_buffers) {
5020 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5021 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5022 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005023#endif
5024
Arun Menon906de572013-06-18 17:01:40 -07005025 post_event(OMX_CommandPortDisable,
5026 OMX_CORE_OUTPUT_PORT_INDEX,
5027 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005028 }
Arun Menon906de572013-06-18 17:01:40 -07005029 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005030 eRet = OMX_ErrorBadPortIndex;
5031 }
Arun Menon906de572013-06-18 17:01:40 -07005032 if ((eRet == OMX_ErrorNone) &&
5033 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5034 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005035 // Send the callback now
5036 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5037 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005038 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005039 }
5040 }
5041 return eRet;
5042}
5043
5044
5045/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005046 FUNCTION
5047 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005048
Arun Menon906de572013-06-18 17:01:40 -07005049 DESCRIPTION
5050 This routine is used to push the encoded video frames to
5051 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005052
Arun Menon906de572013-06-18 17:01:40 -07005053 PARAMETERS
5054 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005055
Arun Menon906de572013-06-18 17:01:40 -07005056 RETURN VALUE
5057 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005058
Arun Menon906de572013-06-18 17:01:40 -07005059 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005060OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005061 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005062{
Arun Menon906de572013-06-18 17:01:40 -07005063 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5064 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005065
Arun Menon906de572013-06-18 17:01:40 -07005066 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5067 codec_config_flag = true;
5068 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5069 } else {
5070 codec_config_flag = false;
5071 }
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07005072
Arun Menon906de572013-06-18 17:01:40 -07005073 if (m_state == OMX_StateInvalid) {
5074 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5075 return OMX_ErrorInvalidState;
5076 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005077
Arun Menon906de572013-06-18 17:01:40 -07005078 if (buffer == NULL) {
5079 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5080 return OMX_ErrorBadParameter;
5081 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005082
Arun Menon906de572013-06-18 17:01:40 -07005083 if (!m_inp_bEnabled) {
5084 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5085 return OMX_ErrorIncorrectStateOperation;
5086 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005087
Arun Menon906de572013-06-18 17:01:40 -07005088 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
5089 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
5090 return OMX_ErrorBadPortIndex;
5091 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005092
5093#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005094 if (iDivXDrmDecrypt) {
5095 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5096 if (drmErr != OMX_ErrorNone) {
5097 // this error can be ignored
5098 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5099 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005100 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005101#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005102 if (perf_flag) {
5103 if (!latency) {
5104 dec_time.stop();
5105 latency = dec_time.processing_time_us();
5106 dec_time.start();
5107 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005108 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005109
Arun Menon906de572013-06-18 17:01:40 -07005110 if (arbitrary_bytes) {
5111 nBufferIndex = buffer - m_inp_heap_ptr;
5112 } else {
5113 if (input_use_buffer == true) {
5114 nBufferIndex = buffer - m_inp_heap_ptr;
5115 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5116 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5117 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5118 buffer = &m_inp_mem_ptr[nBufferIndex];
5119 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5120 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5121 } else {
5122 nBufferIndex = buffer - m_inp_mem_ptr;
5123 }
5124 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005125
Arun Menon906de572013-06-18 17:01:40 -07005126 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
5127 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5128 return OMX_ErrorBadParameter;
5129 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005130
Arun Menon906de572013-06-18 17:01:40 -07005131 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5132 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5133 if (arbitrary_bytes) {
5134 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005135 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005136 } else {
5137 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5138 set_frame_rate(buffer->nTimeStamp);
5139 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5140 }
5141 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005142}
5143
5144/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005145 FUNCTION
5146 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005147
Arun Menon906de572013-06-18 17:01:40 -07005148 DESCRIPTION
5149 This routine is used to push the encoded video frames to
5150 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005151
Arun Menon906de572013-06-18 17:01:40 -07005152 PARAMETERS
5153 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005154
Arun Menon906de572013-06-18 17:01:40 -07005155 RETURN VALUE
5156 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005157
Arun Menon906de572013-06-18 17:01:40 -07005158 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005159OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005160 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005161{
Arun Menon906de572013-06-18 17:01:40 -07005162 int push_cnt = 0,i=0;
5163 unsigned nPortIndex = 0;
5164 OMX_ERRORTYPE ret = OMX_ErrorNone;
5165 struct vdec_input_frameinfo frameinfo;
5166 struct vdec_bufferpayload *temp_buffer;
5167 struct vdec_seqheader seq_header;
5168 bool port_setting_changed = true;
5169 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005170
Arun Menon906de572013-06-18 17:01:40 -07005171 /*Should we generate a Aync error event*/
5172 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
5173 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5174 return OMX_ErrorBadParameter;
5175 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005176
Arun Menon906de572013-06-18 17:01:40 -07005177 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005178
Arun Menon906de572013-06-18 17:01:40 -07005179 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
5180 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5181 nPortIndex);
5182 return OMX_ErrorBadParameter;
5183 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005184
Arun Menon906de572013-06-18 17:01:40 -07005185 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005186
Arun Menon906de572013-06-18 17:01:40 -07005187 /* return zero length and not an EOS buffer */
5188 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5189 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
5190 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5191 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5192 OMX_COMPONENT_GENERATE_EBD);
5193 return OMX_ErrorNone;
5194 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005195
5196
Arun Menon906de572013-06-18 17:01:40 -07005197 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5198 mp4StreamType psBits;
5199 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5200 psBits.numBytes = buffer->nFilledLen;
5201 mp4_headerparser.parseHeader(&psBits);
5202 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5203 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5204 if (not_coded_vop) {
5205 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
5206 buffer->nFilledLen,frame_count);
5207 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
5208 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5209 not_coded_vop = false;
5210 buffer->nFilledLen = 0;
5211 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005212 }
5213 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005214
Arun Menon906de572013-06-18 17:01:40 -07005215 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005216
Arun Menon906de572013-06-18 17:01:40 -07005217 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005218
Arun Menon906de572013-06-18 17:01:40 -07005219 ) {
5220 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5221 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5222 OMX_COMPONENT_GENERATE_EBD);
5223 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005224 }
5225
Arun Menon906de572013-06-18 17:01:40 -07005226 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005227
Arun Menon906de572013-06-18 17:01:40 -07005228 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) {
5229 return OMX_ErrorBadParameter;
5230 }
5231 /* If its first frame, H264 codec and reject is true, then parse the nal
5232 and get the profile. Based on this, reject the clip playback */
5233 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5234 m_reject_avc_1080p_mp) {
5235 first_frame = 1;
5236 DEBUG_PRINT_ERROR("\nParse nal to get the profile");
5237 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5238 NALU_TYPE_SPS);
5239 m_profile = h264_parser->get_profile();
5240 ret = is_video_session_supported();
5241 if (ret) {
5242 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5243 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5244 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5245 m_state = OMX_StateInvalid;
5246 return OMX_ErrorNone;
5247 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005248 }
5249
Arun Menon906de572013-06-18 17:01:40 -07005250 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5251 /*for use buffer we need to memcpy the data*/
5252 temp_buffer->buffer_len = buffer->nFilledLen;
5253
5254 if (input_use_buffer) {
5255 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5256 if (arbitrary_bytes) {
5257 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5258 } else {
5259 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5260 buffer->nFilledLen);
5261 }
5262 } else {
5263 return OMX_ErrorBadParameter;
5264 }
5265
5266 }
5267
5268 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5269 frameinfo.client_data = (void *) buffer;
5270 frameinfo.datalen = temp_buffer->buffer_len;
5271 frameinfo.flags = 0;
5272 frameinfo.offset = buffer->nOffset;
5273 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5274 frameinfo.pmem_offset = temp_buffer->offset;
5275 frameinfo.timestamp = buffer->nTimeStamp;
5276 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5277 DEBUG_PRINT_LOW("ETB: dmx enabled");
5278 if (m_demux_entries == 0) {
5279 extract_demux_addr_offsets(buffer);
5280 }
5281
5282 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5283 handle_demux_data(buffer);
5284 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5285 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5286 } else {
5287 frameinfo.desc_addr = NULL;
5288 frameinfo.desc_size = 0;
5289 }
5290 if (!arbitrary_bytes) {
5291 frameinfo.flags |= buffer->nFlags;
5292 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005293
5294#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005295 if (m_debug_timestamp) {
5296 if (arbitrary_bytes) {
5297 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5298 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5299 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5300 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5301 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5302 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005303 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005304#endif
5305
5306#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07005307 if (output_capability == V4L2_PIX_FMT_VP8) {
5308 struct vp8_ivf_frame_header {
5309 OMX_U32 framesize;
5310 OMX_U32 timestamp_lo;
5311 OMX_U32 timestamp_hi;
5312 } vp8_frame_header;
5313 vp8_frame_header.framesize = temp_buffer->buffer_len;
5314 /* Currently FW doesn't use timestamp values */
5315 vp8_frame_header.timestamp_lo = 0;
5316 vp8_frame_header.timestamp_hi = 0;
5317 if (inputBufferFile1) {
5318 fwrite((const char *)&vp8_frame_header,
5319 sizeof(vp8_frame_header),1,inputBufferFile1);
5320 fwrite((const char *)temp_buffer->bufferaddr,
5321 temp_buffer->buffer_len,1,inputBufferFile1);
5322 }
5323 } else {
5324 if (inputBufferFile1) {
5325 fwrite((const char *)temp_buffer->bufferaddr,
5326 temp_buffer->buffer_len,1,inputBufferFile1);
5327 }
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07005328 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005329#endif
5330
Arun Menon906de572013-06-18 17:01:40 -07005331 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
5332 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5333 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5334 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005335
Arun Menon906de572013-06-18 17:01:40 -07005336 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5337 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5338 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5339 h264_scratch.nFilledLen = 0;
5340 nal_count = 0;
5341 look_ahead_nal = false;
5342 frame_count = 0;
5343 if (m_frame_parser.mutils)
5344 m_frame_parser.mutils->initialize_frame_checking_environment();
5345 m_frame_parser.flush();
5346 h264_last_au_ts = LLONG_MAX;
5347 h264_last_au_flags = 0;
5348 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5349 m_demux_entries = 0;
5350 }
5351 struct v4l2_buffer buf;
5352 struct v4l2_plane plane;
5353 memset( (void *)&buf, 0, sizeof(buf));
5354 memset( (void *)&plane, 0, sizeof(plane));
5355 int rc;
5356 unsigned long print_count;
5357 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5358 buf.flags = V4L2_BUF_FLAG_EOS;
5359 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
5360 }
5361 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5362 buf.index = nPortIndex;
5363 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5364 buf.memory = V4L2_MEMORY_USERPTR;
5365 plane.bytesused = temp_buffer->buffer_len;
5366 plane.length = drv_ctx.ip_buf.buffer_size;
5367 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5368 (unsigned long)temp_buffer->offset;
5369 plane.reserved[0] = temp_buffer->pmem_fd;
5370 plane.reserved[1] = temp_buffer->offset;
5371 plane.data_offset = 0;
5372 buf.m.planes = &plane;
5373 buf.length = 1;
5374 if (frameinfo.timestamp >= LLONG_MAX) {
5375 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5376 }
5377 //assumption is that timestamp is in milliseconds
5378 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5379 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5380 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5381 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005382
Arun Menon906de572013-06-18 17:01:40 -07005383 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5384 if (rc) {
5385 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5386 return OMX_ErrorHardware;
5387 }
5388 if (!streaming[OUTPUT_PORT]) {
5389 enum v4l2_buf_type buf_type;
5390 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005391
Arun Menon906de572013-06-18 17:01:40 -07005392 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005393 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
Arun Menon906de572013-06-18 17:01:40 -07005394 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5395 if (!ret) {
5396 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
5397 streaming[OUTPUT_PORT] = true;
5398 } else {
5399 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
5400 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5401 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5402 OMX_COMPONENT_GENERATE_EBD);
5403 return OMX_ErrorBadParameter;
5404 }
5405 }
5406 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5407 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5408 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005409
Arun Menon906de572013-06-18 17:01:40 -07005410 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005411}
5412
5413/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005414 FUNCTION
5415 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005416
Arun Menon906de572013-06-18 17:01:40 -07005417 DESCRIPTION
5418 IL client uses this method to release the frame buffer
5419 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005420
Arun Menon906de572013-06-18 17:01:40 -07005421 PARAMETERS
5422 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005423
Arun Menon906de572013-06-18 17:01:40 -07005424 RETURN VALUE
5425 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005426
Arun Menon906de572013-06-18 17:01:40 -07005427 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005428OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005429 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005430{
5431
Arun Menon906de572013-06-18 17:01:40 -07005432 if (m_state == OMX_StateInvalid) {
5433 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5434 return OMX_ErrorInvalidState;
5435 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005436
Arun Menon906de572013-06-18 17:01:40 -07005437 if (!m_out_bEnabled) {
5438 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5439 return OMX_ErrorIncorrectStateOperation;
5440 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005441
Arun Menon906de572013-06-18 17:01:40 -07005442 if (buffer == NULL ||
5443 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) {
5444 return OMX_ErrorBadParameter;
5445 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005446
Arun Menon906de572013-06-18 17:01:40 -07005447 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
5448 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
5449 return OMX_ErrorBadPortIndex;
5450 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005451
Arun Menon906de572013-06-18 17:01:40 -07005452 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5453 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5454 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005455}
5456/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005457 FUNCTION
5458 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005459
Arun Menon906de572013-06-18 17:01:40 -07005460 DESCRIPTION
5461 IL client uses this method to release the frame buffer
5462 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005463
Arun Menon906de572013-06-18 17:01:40 -07005464 PARAMETERS
5465 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005466
Arun Menon906de572013-06-18 17:01:40 -07005467 RETURN VALUE
5468 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005469
Arun Menon906de572013-06-18 17:01:40 -07005470 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005471OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005472 OMX_IN OMX_HANDLETYPE hComp,
5473 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005474{
Arun Menon906de572013-06-18 17:01:40 -07005475 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5476 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5477 unsigned nPortIndex = 0;
5478 struct vdec_fillbuffer_cmd fillbuffer;
5479 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5480 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005481
Arun Menon906de572013-06-18 17:01:40 -07005482 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005483
Arun Menon906de572013-06-18 17:01:40 -07005484 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5485 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005486
Arun Menon906de572013-06-18 17:01:40 -07005487 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5488 bufferAdd, bufferAdd->pBuffer);
5489 /*Return back the output buffer to client*/
5490 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
5491 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5492 buffer->nFilledLen = 0;
5493 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5494 return OMX_ErrorNone;
5495 }
5496 pending_output_buffers++;
5497 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5498 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5499 if (ptr_respbuffer) {
5500 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5501 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005502
Arun Menon906de572013-06-18 17:01:40 -07005503 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5504 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5505 buffer->nFilledLen = 0;
5506 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5507 pending_output_buffers--;
5508 return OMX_ErrorBadParameter;
5509 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005510
Arun Menon906de572013-06-18 17:01:40 -07005511 /* memcpy (&fillbuffer.buffer,ptr_outputbuffer,
5512 sizeof(struct vdec_bufferpayload));
5513 fillbuffer.client_data = bufferAdd;*/
Shalaj Jain273b3e02012-06-22 19:08:03 -07005514
5515#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005516 if (m_enable_android_native_buffers) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005517 // Acquire a write lock on this buffer.
5518 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
Arun Menon906de572013-06-18 17:01:40 -07005519 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005520 DEBUG_PRINT_ERROR("Failed to acquire genlock");
5521 buffer->nFilledLen = 0;
5522 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5523 pending_output_buffers--;
5524 return OMX_ErrorInsufficientResources;
5525 } else {
5526 native_buffer[buffer - m_out_mem_ptr].inuse = true;
Arun Menon906de572013-06-18 17:01:40 -07005527 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005528 }
5529#endif
Arun Menon906de572013-06-18 17:01:40 -07005530 int rc = 0;
5531 struct v4l2_buffer buf;
5532 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5533 memset( (void *)&buf, 0, sizeof(buf));
5534 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5535 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005536
Arun Menon906de572013-06-18 17:01:40 -07005537 buf.index = nPortIndex;
5538 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5539 buf.memory = V4L2_MEMORY_USERPTR;
5540 plane[0].bytesused = buffer->nFilledLen;
5541 plane[0].length = drv_ctx.op_buf.buffer_size;
5542 plane[0].m.userptr =
5543 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5544 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5545 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5546 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5547 plane[0].data_offset = 0;
5548 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5549 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5550 plane[extra_idx].bytesused = 0;
5551 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5552 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 -07005553#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005554 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005555#endif
Arun Menon906de572013-06-18 17:01:40 -07005556 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5557 plane[extra_idx].data_offset = 0;
5558 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5559 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5560 return OMX_ErrorBadParameter;
5561 }
5562 buf.m.planes = plane;
5563 buf.length = drv_ctx.num_planes;
5564 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5565 if (rc) {
5566 /*TODO: How to handle this case */
5567 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5568 }
5569 //#ifdef _ANDROID_ICS_
5570 // if (m_enable_android_native_buffers)
5571 // {
5572 // Unlock the buffer
5573 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005574 // DEBUG_PRINT_ERROR("Releasing genlock failed");
5575 // return OMX_ErrorInsufficientResources;
5576 /// } else {
Arun Menon906de572013-06-18 17:01:40 -07005577 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
5578 // }
5579 // }
5580 //#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07005581 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
Arun Menon906de572013-06-18 17:01:40 -07005582 // pending_output_buffers--;
5583 // return OMX_ErrorBadParameter;
5584 //}
5585return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005586}
5587
5588/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005589 FUNCTION
5590 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005591
Arun Menon906de572013-06-18 17:01:40 -07005592 DESCRIPTION
5593 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005594
Arun Menon906de572013-06-18 17:01:40 -07005595 PARAMETERS
5596 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005597
Arun Menon906de572013-06-18 17:01:40 -07005598 RETURN VALUE
5599 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005600
Arun Menon906de572013-06-18 17:01:40 -07005601 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005602OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005603 OMX_IN OMX_CALLBACKTYPE* callbacks,
5604 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005605{
5606
Arun Menon906de572013-06-18 17:01:40 -07005607 m_cb = *callbacks;
5608 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5609 m_cb.EventHandler,m_cb.FillBufferDone);
5610 m_app_data = appData;
5611 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005612}
5613
5614/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005615 FUNCTION
5616 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005617
Arun Menon906de572013-06-18 17:01:40 -07005618 DESCRIPTION
5619 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005620
Arun Menon906de572013-06-18 17:01:40 -07005621 PARAMETERS
5622 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005623
Arun Menon906de572013-06-18 17:01:40 -07005624 RETURN VALUE
5625 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005626
Arun Menon906de572013-06-18 17:01:40 -07005627 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005628OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5629{
5630#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005631 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005632 delete iDivXDrmDecrypt;
5633 iDivXDrmDecrypt=NULL;
5634 }
5635#endif //_ANDROID_
5636
Shalaj Jain286b0062013-02-21 20:35:48 -08005637 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005638 if (OMX_StateLoaded != m_state) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005639 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
Arun Menon906de572013-06-18 17:01:40 -07005640 m_state);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005641 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005642 } else {
5643 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005644 }
5645
5646 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005647 if (m_out_mem_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005648 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005649 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5650 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005651#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005652 if (m_enable_android_native_buffers) {
5653 if (native_buffer[i].inuse) {
5654 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
5655 DEBUG_PRINT_ERROR("Unlocking genlock failed");
5656 }
5657 native_buffer[i].inuse = false;
5658 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005659 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005660#endif
5661 }
5662#ifdef _ANDROID_ICS_
5663 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5664#endif
5665 }
5666
5667 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005668 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005669 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005670 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5671 if (m_inp_mem_ptr)
5672 free_input_buffer (i,&m_inp_mem_ptr[i]);
5673 else
5674 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005675 }
5676 }
5677 free_input_buffer_header();
5678 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005679 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005680 free(h264_scratch.pBuffer);
5681 h264_scratch.pBuffer = NULL;
5682 }
5683
Arun Menon906de572013-06-18 17:01:40 -07005684 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005685 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005686 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005687 }
5688
Arun Menon906de572013-06-18 17:01:40 -07005689 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005690 free(m_platform_list);
5691 m_platform_list = NULL;
5692 }
Arun Menon906de572013-06-18 17:01:40 -07005693 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005694 free(m_vendor_config.pData);
5695 m_vendor_config.pData = NULL;
5696 }
5697
5698 // Reset counters in mesg queues
5699 m_ftb_q.m_size=0;
5700 m_cmd_q.m_size=0;
5701 m_etb_q.m_size=0;
5702 m_ftb_q.m_read = m_ftb_q.m_write =0;
5703 m_cmd_q.m_read = m_cmd_q.m_write =0;
5704 m_etb_q.m_read = m_etb_q.m_write =0;
5705#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005706 if (m_debug_timestamp) {
5707 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005708 }
5709#endif
5710
5711 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
5712 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07005713 // NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005714 DEBUG_PRINT_HIGH("\n Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07005715
Shalaj Jain273b3e02012-06-22 19:08:03 -07005716#ifdef INPUT_BUFFER_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07005717 if (inputBufferFile1)
5718 fclose (inputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005719#endif
5720#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07005721 if (outputBufferFile1)
Shalaj Jainaf08f302013-03-18 13:15:35 -07005722 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005723#endif
5724#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07005725 if (outputExtradataFile)
5726 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005727#endif
Arun Menon906de572013-06-18 17:01:40 -07005728 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
5729 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005730}
5731
5732/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005733 FUNCTION
5734 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07005735
Arun Menon906de572013-06-18 17:01:40 -07005736 DESCRIPTION
5737 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005738
Arun Menon906de572013-06-18 17:01:40 -07005739 PARAMETERS
5740 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005741
Arun Menon906de572013-06-18 17:01:40 -07005742 RETURN VALUE
5743 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005744
Arun Menon906de572013-06-18 17:01:40 -07005745 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005746OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005747 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5748 OMX_IN OMX_U32 port,
5749 OMX_IN OMX_PTR appData,
5750 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005751{
Arun Menon906de572013-06-18 17:01:40 -07005752 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
5753 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
5754 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005755
5756#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005757 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
5758 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005759#else
Arun Menon906de572013-06-18 17:01:40 -07005760 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005761#endif
Arun Menon906de572013-06-18 17:01:40 -07005762 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
5763 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
5764 DEBUG_PRINT_ERROR("\n ");
5765 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005766#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005767 if (m_display_id == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005768 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
5769 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005770 }
5771 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
5772 eglGetProcAddress("eglQueryImageKHR");
5773 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
5774 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
5775 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005776#else //with OMX test app
5777 struct temp_egl {
5778 int pmem_fd;
5779 int offset;
5780 };
5781 struct temp_egl *temp_egl_id = NULL;
5782 void * pmemPtr = (void *) eglImage;
5783 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07005784 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005785 fd = temp_egl_id->pmem_fd;
5786 offset = temp_egl_id->offset;
5787 }
5788#endif
5789 if (fd < 0) {
5790 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
5791 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005792 }
5793 pmem_info.pmem_fd = (OMX_U32) fd;
5794 pmem_info.offset = (OMX_U32) offset;
5795 pmem_entry.entry = (void *) &pmem_info;
5796 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5797 pmem_list.entryList = &pmem_entry;
5798 pmem_list.nEntries = 1;
5799 ouput_egl_buffers = true;
5800 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
5801 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
5802 (OMX_U8 *)pmemPtr)) {
5803 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
5804 return OMX_ErrorInsufficientResources;
5805 }
5806 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005807}
5808
5809/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005810 FUNCTION
5811 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07005812
Arun Menon906de572013-06-18 17:01:40 -07005813 DESCRIPTION
5814 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005815
Arun Menon906de572013-06-18 17:01:40 -07005816 PARAMETERS
5817 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005818
Arun Menon906de572013-06-18 17:01:40 -07005819 RETURN VALUE
5820 OMX Error None if everything is successful.
5821 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005822OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005823 OMX_OUT OMX_U8* role,
5824 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005825{
Arun Menon906de572013-06-18 17:01:40 -07005826 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005827
Arun Menon906de572013-06-18 17:01:40 -07005828 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
5829 if ((0 == index) && role) {
5830 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
5831 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5832 } else {
5833 eRet = OMX_ErrorNoMore;
5834 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005835 }
Arun Menon906de572013-06-18 17:01:40 -07005836 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
5837 if ((0 == index) && role) {
5838 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
5839 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5840 } else {
5841 eRet = OMX_ErrorNoMore;
5842 }
5843 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
5844 if ((0 == index) && role) {
5845 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
5846 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5847 } else {
5848 DEBUG_PRINT_LOW("\n No more roles \n");
5849 eRet = OMX_ErrorNoMore;
5850 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005851 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005852
Arun Menon906de572013-06-18 17:01:40 -07005853 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
5854 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
5855 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07005856
Shalaj Jain273b3e02012-06-22 19:08:03 -07005857 {
Arun Menon906de572013-06-18 17:01:40 -07005858 if ((0 == index) && role) {
5859 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
5860 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5861 } else {
5862 DEBUG_PRINT_LOW("\n No more roles \n");
5863 eRet = OMX_ErrorNoMore;
5864 }
5865 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
5866 if ((0 == index) && role) {
5867 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
5868 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5869 } else {
5870 DEBUG_PRINT_LOW("\n No more roles \n");
5871 eRet = OMX_ErrorNoMore;
5872 }
5873 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
5874 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
5875 ) {
5876 if ((0 == index) && role) {
5877 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
5878 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5879 } else {
5880 DEBUG_PRINT_LOW("\n No more roles \n");
5881 eRet = OMX_ErrorNoMore;
5882 }
5883 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
5884 if ((0 == index) && role) {
5885 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
5886 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5887 } else {
5888 DEBUG_PRINT_LOW("\n No more roles \n");
5889 eRet = OMX_ErrorNoMore;
5890 }
5891 } else {
5892 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
5893 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005894 }
Arun Menon906de572013-06-18 17:01:40 -07005895 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005896}
5897
5898
5899
5900
5901/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005902 FUNCTION
5903 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07005904
Arun Menon906de572013-06-18 17:01:40 -07005905 DESCRIPTION
5906 Checks if entire buffer pool is allocated by IL Client or not.
5907 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005908
Arun Menon906de572013-06-18 17:01:40 -07005909 PARAMETERS
5910 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005911
Arun Menon906de572013-06-18 17:01:40 -07005912 RETURN VALUE
5913 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005914
Arun Menon906de572013-06-18 17:01:40 -07005915 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005916bool omx_vdec::allocate_done(void)
5917{
Arun Menon906de572013-06-18 17:01:40 -07005918 bool bRet = false;
5919 bool bRet_In = false;
5920 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005921
Arun Menon906de572013-06-18 17:01:40 -07005922 bRet_In = allocate_input_done();
5923 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005924
Arun Menon906de572013-06-18 17:01:40 -07005925 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005926 bRet = true;
5927 }
Arun Menon906de572013-06-18 17:01:40 -07005928
5929 return bRet;
5930}
5931/* ======================================================================
5932 FUNCTION
5933 omx_vdec::AllocateInputDone
5934
5935 DESCRIPTION
5936 Checks if I/P buffer pool is allocated by IL Client or not.
5937
5938 PARAMETERS
5939 None.
5940
5941 RETURN VALUE
5942 true/false.
5943
5944 ========================================================================== */
5945bool omx_vdec::allocate_input_done(void)
5946{
5947 bool bRet = false;
5948 unsigned i=0;
5949
5950 if (m_inp_mem_ptr == NULL) {
5951 return bRet;
5952 }
5953 if (m_inp_mem_ptr ) {
5954 for (; i<drv_ctx.ip_buf.actualcount; i++) {
5955 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
5956 break;
5957 }
5958 }
5959 }
5960 if (i == drv_ctx.ip_buf.actualcount) {
5961 bRet = true;
5962 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
5963 }
5964 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
5965 m_inp_bPopulated = OMX_TRUE;
5966 }
5967 return bRet;
5968}
5969/* ======================================================================
5970 FUNCTION
5971 omx_vdec::AllocateOutputDone
5972
5973 DESCRIPTION
5974 Checks if entire O/P buffer pool is allocated by IL Client or not.
5975
5976 PARAMETERS
5977 None.
5978
5979 RETURN VALUE
5980 true/false.
5981
5982 ========================================================================== */
5983bool omx_vdec::allocate_output_done(void)
5984{
5985 bool bRet = false;
5986 unsigned j=0;
5987
5988 if (m_out_mem_ptr == NULL) {
5989 return bRet;
5990 }
5991
5992 if (m_out_mem_ptr) {
5993 for (; j < drv_ctx.op_buf.actualcount; j++) {
5994 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
5995 break;
5996 }
5997 }
5998 }
5999
6000 if (j == drv_ctx.op_buf.actualcount) {
6001 bRet = true;
6002 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6003 if (m_out_bEnabled)
6004 m_out_bPopulated = OMX_TRUE;
6005 }
6006
6007 return bRet;
6008}
6009
6010/* ======================================================================
6011 FUNCTION
6012 omx_vdec::ReleaseDone
6013
6014 DESCRIPTION
6015 Checks if IL client has released all the buffers.
6016
6017 PARAMETERS
6018 None.
6019
6020 RETURN VALUE
6021 true/false
6022
6023 ========================================================================== */
6024bool omx_vdec::release_done(void)
6025{
6026 bool bRet = false;
6027
6028 if (release_input_done()) {
6029 if (release_output_done()) {
6030 bRet = true;
6031 }
6032 }
6033 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006034}
6035
6036
6037/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006038 FUNCTION
6039 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006040
Arun Menon906de572013-06-18 17:01:40 -07006041 DESCRIPTION
6042 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006043
Arun Menon906de572013-06-18 17:01:40 -07006044 PARAMETERS
6045 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006046
Arun Menon906de572013-06-18 17:01:40 -07006047 RETURN VALUE
6048 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006049
Arun Menon906de572013-06-18 17:01:40 -07006050 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006051bool omx_vdec::release_output_done(void)
6052{
Arun Menon906de572013-06-18 17:01:40 -07006053 bool bRet = false;
6054 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006055
Arun Menon906de572013-06-18 17:01:40 -07006056 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6057 if (m_out_mem_ptr) {
6058 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6059 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6060 break;
6061 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006062 }
Arun Menon906de572013-06-18 17:01:40 -07006063 if (j == drv_ctx.op_buf.actualcount) {
6064 m_out_bm_count = 0;
6065 bRet = true;
6066 }
6067 } else {
6068 m_out_bm_count = 0;
6069 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006070 }
Arun Menon906de572013-06-18 17:01:40 -07006071 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006072}
6073/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006074 FUNCTION
6075 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006076
Arun Menon906de572013-06-18 17:01:40 -07006077 DESCRIPTION
6078 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006079
Arun Menon906de572013-06-18 17:01:40 -07006080 PARAMETERS
6081 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006082
Arun Menon906de572013-06-18 17:01:40 -07006083 RETURN VALUE
6084 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006085
Arun Menon906de572013-06-18 17:01:40 -07006086 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006087bool omx_vdec::release_input_done(void)
6088{
Arun Menon906de572013-06-18 17:01:40 -07006089 bool bRet = false;
6090 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006091
Arun Menon906de572013-06-18 17:01:40 -07006092 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6093 if (m_inp_mem_ptr) {
6094 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6095 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6096 break;
6097 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006098 }
Arun Menon906de572013-06-18 17:01:40 -07006099 if (j==drv_ctx.ip_buf.actualcount) {
6100 bRet = true;
6101 }
6102 } else {
6103 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006104 }
Arun Menon906de572013-06-18 17:01:40 -07006105 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006106}
6107
6108OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006109 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006110{
Arun Menon906de572013-06-18 17:01:40 -07006111 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6112 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) {
6113 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6114 return OMX_ErrorBadParameter;
6115 } else if (output_flush_progress) {
6116 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6117 buffer->nFilledLen = 0;
6118 buffer->nTimeStamp = 0;
6119 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6120 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6121 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006122 }
6123
Arun Menon906de572013-06-18 17:01:40 -07006124 if (m_debug_extradata) {
6125 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
6126 DEBUG_PRINT_HIGH("\n");
6127 DEBUG_PRINT_HIGH("***************************************************\n");
6128 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
6129 DEBUG_PRINT_HIGH("***************************************************\n");
6130 }
6131
6132 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
6133 DEBUG_PRINT_HIGH("\n");
6134 DEBUG_PRINT_HIGH("***************************************************\n");
6135 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
6136 DEBUG_PRINT_HIGH("***************************************************\n");
6137 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006138 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006139
6140
Arun Menon906de572013-06-18 17:01:40 -07006141 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6142 buffer, buffer->pBuffer);
6143 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006144
Arun Menon906de572013-06-18 17:01:40 -07006145 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6146 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6147 if (!output_flush_progress)
6148 post_event((unsigned)NULL, (unsigned)NULL,
6149 OMX_COMPONENT_GENERATE_EOS_DONE);
6150
6151 if (psource_frame) {
6152 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6153 psource_frame = NULL;
6154 }
6155 if (pdest_frame) {
6156 pdest_frame->nFilledLen = 0;
6157 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6158 (unsigned)NULL);
6159 pdest_frame = NULL;
6160 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006161 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006162
Arun Menon906de572013-06-18 17:01:40 -07006163 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006164#ifdef OUTPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07006165 if (outputBufferFile1 && buffer->nFilledLen) {
6166 int buf_index = buffer - m_out_mem_ptr;
6167 int stride = drv_ctx.video_resolution.stride;
6168 int scanlines = drv_ctx.video_resolution.scan_lines;
6169 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
6170 unsigned i;
6171 int bytes_written = 0;
6172 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6173 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6174 temp += stride;
6175 }
6176 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
6177 int stride_c = stride;
6178 for (i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6179 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6180 temp += stride_c;
6181 }
6182 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006183#endif
6184
Arun Menon906de572013-06-18 17:01:40 -07006185 /* For use buffer we need to copy the data */
6186 if (!output_flush_progress) {
6187 /* This is the error check for non-recoverable errros */
6188 bool is_duplicate_ts_valid = true;
6189 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006190
Arun Menon906de572013-06-18 17:01:40 -07006191 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6192 output_capability == V4L2_PIX_FMT_MPEG2 ||
6193 output_capability == V4L2_PIX_FMT_DIVX ||
6194 output_capability == V4L2_PIX_FMT_DIVX_311)
6195 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006196
Arun Menon906de572013-06-18 17:01:40 -07006197 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6198 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6199 if (mbaff) {
6200 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306201 }
Arun Menon906de572013-06-18 17:01:40 -07006202 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306203
Arun Menon906de572013-06-18 17:01:40 -07006204 if (buffer->nFilledLen > 0) {
6205 time_stamp_dts.get_next_timestamp(buffer,
6206 is_interlaced && is_duplicate_ts_valid);
6207 if (m_debug_timestamp) {
6208 {
6209 OMX_TICKS expected_ts = 0;
6210 m_timestamp_list.pop_min_ts(expected_ts);
6211 if (is_interlaced && is_duplicate_ts_valid) {
6212 m_timestamp_list.pop_min_ts(expected_ts);
6213 }
6214 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6215 buffer->nTimeStamp, expected_ts);
6216
6217 if (buffer->nTimeStamp != expected_ts) {
6218 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6219 }
6220 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306221 }
Arun Menon906de572013-06-18 17:01:40 -07006222 } else {
6223 m_inp_err_count++;
6224 time_stamp_dts.remove_time_stamp(
6225 buffer->nTimeStamp,
6226 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306227 }
Arun Menon906de572013-06-18 17:01:40 -07006228
6229
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006230 }
Arun Menon906de572013-06-18 17:01:40 -07006231 if (m_cb.FillBufferDone) {
6232 if (buffer->nFilledLen > 0) {
6233 handle_extradata(buffer);
6234 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6235 set_frame_rate(buffer->nTimeStamp);
6236 else if (arbitrary_bytes)
6237 adjust_timestamp(buffer->nTimeStamp);
6238 if (perf_flag) {
6239 if (!proc_frms) {
6240 dec_time.stop();
6241 latency = dec_time.processing_time_us() - latency;
6242 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6243 dec_time.start();
6244 fps_metrics.start();
6245 }
6246 proc_frms++;
6247 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6248 OMX_U64 proc_time = 0;
6249 fps_metrics.stop();
6250 proc_time = fps_metrics.processing_time_us();
6251 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006252 proc_frms, (float)proc_time / 1e6,
6253 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006254 proc_frms = 0;
6255 }
6256 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006257
6258#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006259 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006260
Arun Menon906de572013-06-18 17:01:40 -07006261 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6262 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6263 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6264 buffer->nFilledLen + 3)&(~3));
6265 while (p_extra &&
6266 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
6267 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6268 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6269 if (p_extra->eType == OMX_ExtraDataNone) {
6270 break;
6271 }
6272 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6273 }
6274 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006275#endif
Arun Menon906de572013-06-18 17:01:40 -07006276 }
6277 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6278 prev_ts = LLONG_MAX;
6279 rst_prev_ts = true;
6280 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006281
Arun Menon906de572013-06-18 17:01:40 -07006282 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6283 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6284 buffer->pPlatformPrivate)->entryList->entry;
6285 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006286#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07006287 if (m_enable_android_native_buffers) {
6288 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6289 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6290 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6291 return OMX_ErrorInsufficientResources;
6292 } else {
6293 native_buffer[buffer - m_out_mem_ptr].inuse = false;
6294 }
6295 }
6296 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006297#endif
Arun Menon906de572013-06-18 17:01:40 -07006298 OMX_BUFFERHEADERTYPE *il_buffer;
6299 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6300 if (il_buffer)
6301 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6302 else {
6303 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6304 return OMX_ErrorBadParameter;
6305 }
6306 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
6307 } else {
6308 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006309 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006310
Arun Menon906de572013-06-18 17:01:40 -07006311 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006312}
6313
6314OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006315 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006316{
6317
Arun Menon906de572013-06-18 17:01:40 -07006318 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006319 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006320 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006321 }
6322
6323 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006324 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006325 pending_input_buffers--;
6326
Arun Menon906de572013-06-18 17:01:40 -07006327 if (arbitrary_bytes) {
6328 if (pdest_frame == NULL && input_flush_progress == false) {
6329 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6330 pdest_frame = buffer;
6331 buffer->nFilledLen = 0;
6332 buffer->nTimeStamp = LLONG_MAX;
6333 push_input_buffer (hComp);
6334 } else {
6335 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6336 buffer->nFilledLen = 0;
6337 if (!m_input_free_q.insert_entry((unsigned)buffer,
6338 (unsigned)NULL, (unsigned)NULL)) {
6339 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6340 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006341 }
Arun Menon906de572013-06-18 17:01:40 -07006342 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006343 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006344 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006345 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6346 }
6347 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6348 }
6349 return OMX_ErrorNone;
6350}
6351
Shalaj Jain273b3e02012-06-22 19:08:03 -07006352int omx_vdec::async_message_process (void *context, void* message)
6353{
Arun Menon906de572013-06-18 17:01:40 -07006354 omx_vdec* omx = NULL;
6355 struct vdec_msginfo *vdec_msg = NULL;
6356 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6357 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6358 struct vdec_output_frameinfo *output_respbuf = NULL;
6359 int rc=1;
6360 if (context == NULL || message == NULL) {
6361 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6362 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006363 }
Arun Menon906de572013-06-18 17:01:40 -07006364 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006365
Arun Menon906de572013-06-18 17:01:40 -07006366 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006367
Arun Menon906de572013-06-18 17:01:40 -07006368 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006369
Arun Menon906de572013-06-18 17:01:40 -07006370 case VDEC_MSG_EVT_HW_ERROR:
6371 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6372 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6373 break;
6374
6375 case VDEC_MSG_RESP_START_DONE:
6376 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6377 OMX_COMPONENT_GENERATE_START_DONE);
6378 break;
6379
6380 case VDEC_MSG_RESP_STOP_DONE:
6381 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6382 OMX_COMPONENT_GENERATE_STOP_DONE);
6383 break;
6384
6385 case VDEC_MSG_RESP_RESUME_DONE:
6386 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6387 OMX_COMPONENT_GENERATE_RESUME_DONE);
6388 break;
6389
6390 case VDEC_MSG_RESP_PAUSE_DONE:
6391 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6392 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6393 break;
6394
6395 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6396 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6397 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6398 break;
6399 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6400 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6401 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6402 break;
6403 case VDEC_MSG_RESP_INPUT_FLUSHED:
6404 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6405
6406 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6407 vdec_msg->msgdata.input_frame_clientdata; */
6408
6409 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6410 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6411 if (omxhdr == NULL ||
6412 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) {
6413 omxhdr = NULL;
6414 vdec_msg->status_code = VDEC_S_EFATAL;
6415 }
6416 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6417 DEBUG_PRINT_HIGH("Unsupported input");
6418 omx->omx_report_error ();
6419 }
6420 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6421 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6422 }
6423 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6424 OMX_COMPONENT_GENERATE_EBD);
6425 break;
6426 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6427 int64_t *timestamp;
6428 timestamp = (int64_t *) malloc(sizeof(int64_t));
6429 if (timestamp) {
6430 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6431 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6432 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6433 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6434 vdec_msg->msgdata.output_frame.time_stamp);
6435 }
6436 break;
6437 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6438 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6439
6440 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6441 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6442 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6443 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6444 vdec_msg->msgdata.output_frame.pic_type);
6445
6446 if (omxhdr && omxhdr->pOutputPortPrivate &&
6447 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6448 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6449 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) {
6450 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6451 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6452 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6453 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6454 omxhdr->nFlags = 0;
6455
6456 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS) {
6457 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6458 //rc = -1;
6459 }
6460 if (omxhdr->nFilledLen) {
6461 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6462 }
6463 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6464 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6465 } else {
6466 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6467 }
6468 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6469 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6470 }
6471 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6472 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6473 }
6474 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6475 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
6476 !(v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)) {
6477 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6478 OMX_COMPONENT_GENERATE_FTB);
6479 break;
6480 }
6481 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6482 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6483 }
6484 vdec_msg->msgdata.output_frame.bufferaddr =
6485 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6486 int format_notably_changed = 0;
6487 if (omxhdr->nFilledLen &&
6488 (omxhdr->nFilledLen != omx->prev_n_filled_len)) {
6489 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6490 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6491 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
6492 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6493 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6494 format_notably_changed = 1;
6495 }
6496 }
6497 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6498 vdec_msg->msgdata.output_frame.framesize.left)
6499 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6500 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6501 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6502 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6503 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6504 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6505 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6506 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
6507 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6508 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6509 }
6510 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
6511 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6512 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
6513 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6514 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6515 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6516 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6517 format_notably_changed = 1;
6518 }
6519 if (format_notably_changed) {
6520 if (omx->is_video_session_supported()) {
6521 omx->post_event (NULL, vdec_msg->status_code,
6522 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6523 } else {
6524 if (!omx->client_buffers.update_buffer_req()) {
6525 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6526 }
6527 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6528 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6529 }
6530 }
6531 if (omxhdr->nFilledLen)
6532 omx->prev_n_filled_len = omxhdr->nFilledLen;
6533
6534 output_respbuf = (struct vdec_output_frameinfo *)\
6535 omxhdr->pOutputPortPrivate;
6536 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6537 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6538 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6539 output_respbuf->pic_type = PICTURE_TYPE_I;
6540 }
6541 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6542 output_respbuf->pic_type = PICTURE_TYPE_P;
6543 }
6544 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6545 output_respbuf->pic_type = PICTURE_TYPE_B;
6546 }
6547
6548 if (omx->output_use_buffer)
6549 memcpy ( omxhdr->pBuffer, (void *)
6550 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6551 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6552 vdec_msg->msgdata.output_frame.len);
6553 } else
6554 omxhdr->nFilledLen = 0;
6555 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6556 OMX_COMPONENT_GENERATE_FBD);
6557 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6558 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6559 OMX_COMPONENT_GENERATE_EOS_DONE);
6560 else
6561 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6562 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6563 break;
6564 case VDEC_MSG_EVT_CONFIG_CHANGED:
6565 DEBUG_PRINT_HIGH("\n Port settings changed");
6566 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6567 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6568 break;
6569 default:
6570 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006571 }
Arun Menon906de572013-06-18 17:01:40 -07006572 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006573}
6574
6575OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006576 OMX_HANDLETYPE hComp,
6577 OMX_BUFFERHEADERTYPE *buffer
6578 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006579{
Arun Menon906de572013-06-18 17:01:40 -07006580 unsigned address,p2,id;
6581 DEBUG_PRINT_LOW("\n Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006582
Arun Menon906de572013-06-18 17:01:40 -07006583 if (buffer == NULL) {
6584 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006585 }
Arun Menon906de572013-06-18 17:01:40 -07006586 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6587 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
6588 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6589
6590 /* return zero length and not an EOS buffer */
6591 /* return buffer if input flush in progress */
6592 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6593 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
6594 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
6595 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6596 return OMX_ErrorNone;
6597 }
6598
6599 if (psource_frame == NULL) {
6600 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
6601 psource_frame = buffer;
6602 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
6603 push_input_buffer (hComp);
6604 } else {
6605 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
6606 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6607 (unsigned)NULL)) {
6608 return OMX_ErrorBadParameter;
6609 }
6610 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006611
6612
Arun Menon906de572013-06-18 17:01:40 -07006613 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006614}
6615
6616OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6617{
Arun Menon906de572013-06-18 17:01:40 -07006618 unsigned address,p2,id;
6619 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006620
Arun Menon906de572013-06-18 17:01:40 -07006621 if (pdest_frame == NULL || psource_frame == NULL) {
6622 /*Check if we have a destination buffer*/
6623 if (pdest_frame == NULL) {
6624 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
6625 if (m_input_free_q.m_size) {
6626 m_input_free_q.pop_entry(&address,&p2,&id);
6627 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6628 pdest_frame->nFilledLen = 0;
6629 pdest_frame->nTimeStamp = LLONG_MAX;
6630 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
6631 }
6632 }
6633
6634 /*Check if we have a destination buffer*/
6635 if (psource_frame == NULL) {
6636 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
6637 if (m_input_pending_q.m_size) {
6638 m_input_pending_q.pop_entry(&address,&p2,&id);
6639 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
6640 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6641 psource_frame->nTimeStamp);
6642 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6643 psource_frame->nFlags,psource_frame->nFilledLen);
6644
6645 }
6646 }
6647
Shalaj Jain273b3e02012-06-22 19:08:03 -07006648 }
6649
Arun Menon906de572013-06-18 17:01:40 -07006650 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6651 switch (codec_type_parse) {
6652 case CODEC_TYPE_MPEG4:
6653 case CODEC_TYPE_H263:
6654 case CODEC_TYPE_MPEG2:
6655 ret = push_input_sc_codec(hComp);
6656 break;
6657 case CODEC_TYPE_H264:
6658 ret = push_input_h264(hComp);
6659 break;
6660 case CODEC_TYPE_VC1:
6661 ret = push_input_vc1(hComp);
6662 break;
6663 default:
6664 break;
6665 }
6666 if (ret != OMX_ErrorNone) {
6667 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
6668 omx_report_error ();
6669 break;
6670 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006671 }
6672
Arun Menon906de572013-06-18 17:01:40 -07006673 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006674}
6675
6676OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
6677{
Arun Menon906de572013-06-18 17:01:40 -07006678 OMX_U32 partial_frame = 1;
6679 OMX_BOOL generate_ebd = OMX_TRUE;
6680 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006681
Arun Menon906de572013-06-18 17:01:40 -07006682 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
6683 psource_frame,psource_frame->nTimeStamp);
6684 if (m_frame_parser.parse_sc_frame(psource_frame,
6685 pdest_frame,&partial_frame) == -1) {
6686 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
6687 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006688 }
Arun Menon906de572013-06-18 17:01:40 -07006689
6690 if (partial_frame == 0) {
6691 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
6692 pdest_frame->nFilledLen,psource_frame,frame_count);
6693
6694
6695 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
6696 /*First Parsed buffer will have only header Hence skip*/
6697 if (frame_count == 0) {
6698 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
6699
6700 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
6701 codec_type_parse == CODEC_TYPE_DIVX) {
6702 mp4StreamType psBits;
6703 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
6704 psBits.numBytes = pdest_frame->nFilledLen;
6705 mp4_headerparser.parseHeader(&psBits);
6706 }
6707
6708 frame_count++;
6709 } else {
6710 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6711 if (pdest_frame->nFilledLen) {
6712 /*Push the frame to the Decoder*/
6713 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6714 return OMX_ErrorBadParameter;
6715 }
6716 frame_count++;
6717 pdest_frame = NULL;
6718
6719 if (m_input_free_q.m_size) {
6720 m_input_free_q.pop_entry(&address,&p2,&id);
6721 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6722 pdest_frame->nFilledLen = 0;
6723 }
6724 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
6725 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
6726 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
6727 (unsigned)NULL);
6728 pdest_frame = NULL;
6729 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006730 }
Arun Menon906de572013-06-18 17:01:40 -07006731 } else {
6732 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
6733 /*Check if Destination Buffer is full*/
6734 if (pdest_frame->nAllocLen ==
6735 pdest_frame->nFilledLen + pdest_frame->nOffset) {
6736 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
6737 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006738 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006739 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006740
Arun Menon906de572013-06-18 17:01:40 -07006741 if (psource_frame->nFilledLen == 0) {
6742 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6743 if (pdest_frame) {
6744 pdest_frame->nFlags |= psource_frame->nFlags;
6745 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
6746 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6747 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6748 pdest_frame->nFilledLen,frame_count++);
6749 /*Push the frame to the Decoder*/
6750 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6751 return OMX_ErrorBadParameter;
6752 }
6753 frame_count++;
6754 pdest_frame = NULL;
6755 } else {
6756 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
6757 generate_ebd = OMX_FALSE;
6758 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006759 }
Arun Menon906de572013-06-18 17:01:40 -07006760 if (generate_ebd) {
6761 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
6762 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6763 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006764
Arun Menon906de572013-06-18 17:01:40 -07006765 if (m_input_pending_q.m_size) {
6766 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6767 m_input_pending_q.pop_entry(&address,&p2,&id);
6768 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6769 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6770 psource_frame->nTimeStamp);
6771 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6772 psource_frame->nFlags,psource_frame->nFilledLen);
6773 }
6774 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006775 }
Arun Menon906de572013-06-18 17:01:40 -07006776 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006777}
6778
6779OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
6780{
Arun Menon906de572013-06-18 17:01:40 -07006781 OMX_U32 partial_frame = 1;
6782 unsigned address = 0, p2 = 0, id = 0;
6783 OMX_BOOL isNewFrame = OMX_FALSE;
6784 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006785
Arun Menon906de572013-06-18 17:01:40 -07006786 if (h264_scratch.pBuffer == NULL) {
6787 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
6788 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006789 }
Arun Menon906de572013-06-18 17:01:40 -07006790 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
6791 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
6792 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
6793 if (h264_scratch.nFilledLen && look_ahead_nal) {
6794 look_ahead_nal = false;
6795 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6796 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006797 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6798 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6799 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Arun Menon906de572013-06-18 17:01:40 -07006800 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006801 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006802 } else {
6803 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006804 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006805 }
Arun Menon906de572013-06-18 17:01:40 -07006806 }
6807 if (nal_length == 0) {
6808 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
6809 if (m_frame_parser.parse_sc_frame(psource_frame,
6810 &h264_scratch,&partial_frame) == -1) {
6811 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006812 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006813 }
Arun Menon906de572013-06-18 17:01:40 -07006814 } else {
6815 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
6816 if (m_frame_parser.parse_h264_nallength(psource_frame,
6817 &h264_scratch,&partial_frame) == -1) {
6818 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
6819 return OMX_ErrorBadParameter;
6820 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006821 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006822
Arun Menon906de572013-06-18 17:01:40 -07006823 if (partial_frame == 0) {
6824 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
6825 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
6826 nal_count++;
6827 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
6828 h264_scratch.nFlags = psource_frame->nFlags;
6829 } else {
6830 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
6831 if (h264_scratch.nFilledLen) {
6832 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
6833 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006834#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07006835 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6836 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
6837 h264_scratch.nFilledLen, NALU_TYPE_SEI);
6838 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
6839 // If timeinfo is present frame info from SEI is already processed
6840 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
6841 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006842#endif
Arun Menon906de572013-06-18 17:01:40 -07006843 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
6844 nal_count++;
6845 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
6846 pdest_frame->nTimeStamp = h264_last_au_ts;
6847 pdest_frame->nFlags = h264_last_au_flags;
6848#ifdef PANSCAN_HDLR
6849 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
6850 h264_parser->update_panscan_data(h264_last_au_ts);
6851#endif
6852 }
6853 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
6854 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
6855 h264_last_au_ts = h264_scratch.nTimeStamp;
6856 h264_last_au_flags = h264_scratch.nFlags;
6857#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
6858 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
6859 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
6860 if (!VALID_TS(h264_last_au_ts))
6861 h264_last_au_ts = ts_in_sei;
6862 }
6863#endif
6864 } else
6865 h264_last_au_ts = LLONG_MAX;
6866 }
6867
6868 if (!isNewFrame) {
6869 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6870 h264_scratch.nFilledLen) {
6871 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
6872 h264_scratch.nFilledLen);
6873 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6874 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6875 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6876 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
6877 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6878 h264_scratch.nFilledLen = 0;
6879 } else {
6880 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
6881 return OMX_ErrorBadParameter;
6882 }
6883 } else {
6884 look_ahead_nal = true;
6885 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
6886 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6887 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6888 pdest_frame->nFilledLen,frame_count++);
6889
6890 if (pdest_frame->nFilledLen == 0) {
6891 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
6892 look_ahead_nal = false;
6893 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6894 h264_scratch.nFilledLen) {
6895 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6896 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6897 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6898 h264_scratch.nFilledLen = 0;
6899 } else {
6900 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
6901 return OMX_ErrorBadParameter;
6902 }
6903 } else {
6904 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
6905 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
6906 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6907 }
6908 /*Push the frame to the Decoder*/
6909 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6910 return OMX_ErrorBadParameter;
6911 }
6912 //frame_count++;
6913 pdest_frame = NULL;
6914 if (m_input_free_q.m_size) {
6915 m_input_free_q.pop_entry(&address,&p2,&id);
6916 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6917 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
6918 pdest_frame->nFilledLen = 0;
6919 pdest_frame->nFlags = 0;
6920 pdest_frame->nTimeStamp = LLONG_MAX;
6921 }
6922 }
6923 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006924 }
Arun Menon906de572013-06-18 17:01:40 -07006925 } else {
6926 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
6927 /*Check if Destination Buffer is full*/
6928 if (h264_scratch.nAllocLen ==
6929 h264_scratch.nFilledLen + h264_scratch.nOffset) {
6930 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
6931 return OMX_ErrorStreamCorrupt;
6932 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006933 }
Arun Menon906de572013-06-18 17:01:40 -07006934
6935 if (!psource_frame->nFilledLen) {
6936 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
6937
6938 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6939 if (pdest_frame) {
6940 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
6941 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6942 h264_scratch.nFilledLen) {
6943 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6944 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6945 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6946 h264_scratch.nFilledLen = 0;
6947 } else {
6948 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
6949 return OMX_ErrorBadParameter;
6950 }
6951 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
6952 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
6953
6954 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
6955 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6956 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
6957#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
6958 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
6959 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
6960 if (!VALID_TS(pdest_frame->nTimeStamp))
6961 pdest_frame->nTimeStamp = ts_in_sei;
6962 }
6963#endif
6964 /*Push the frame to the Decoder*/
6965 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6966 return OMX_ErrorBadParameter;
6967 }
6968 frame_count++;
6969 pdest_frame = NULL;
6970 } else {
6971 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
6972 pdest_frame,h264_scratch.nFilledLen);
6973 generate_ebd = OMX_FALSE;
6974 }
6975 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006976 }
Arun Menon906de572013-06-18 17:01:40 -07006977 if (generate_ebd && !psource_frame->nFilledLen) {
6978 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6979 psource_frame = NULL;
6980 if (m_input_pending_q.m_size) {
6981 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6982 m_input_pending_q.pop_entry(&address,&p2,&id);
6983 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6984 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
6985 psource_frame->nFlags,psource_frame->nFilledLen);
6986 }
6987 }
6988 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006989}
6990
6991OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
6992{
6993 OMX_U8 *buf, *pdest;
6994 OMX_U32 partial_frame = 1;
6995 OMX_U32 buf_len, dest_len;
6996
Arun Menon906de572013-06-18 17:01:40 -07006997 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006998 first_frame = 1;
6999 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
Arun Menon906de572013-06-18 17:01:40 -07007000 if (!m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007001 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7002 buf = psource_frame->pBuffer;
7003 buf_len = psource_frame->nFilledLen;
7004
7005 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007006 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007007 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007008 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007009 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007010 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007011 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7012 return OMX_ErrorStreamCorrupt;
7013 }
Arun Menon906de572013-06-18 17:01:40 -07007014 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007015 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7016 pdest_frame->nOffset;
7017 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007018 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007019
Arun Menon906de572013-06-18 17:01:40 -07007020 if (dest_len < m_vendor_config.nDataSize) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007021 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7022 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007023 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007024 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7025 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7026 }
7027 }
7028 }
7029
Arun Menon906de572013-06-18 17:01:40 -07007030 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007031 case VC1_AP:
7032 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007033 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007034 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7035 return OMX_ErrorBadParameter;
7036 }
Arun Menon906de572013-06-18 17:01:40 -07007037 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007038
7039 case VC1_SP_MP_RCV:
7040 default:
7041 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7042 return OMX_ErrorBadParameter;
7043 }
7044 return OMX_ErrorNone;
7045}
7046
David Ng38e2d232013-03-15 20:05:58 -07007047#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007048bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007049 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007050{
Arun Menon906de572013-06-18 17:01:40 -07007051 struct pmem_allocation allocation;
7052 allocation.size = buffer_size;
7053 allocation.align = clip2(alignment);
7054 if (allocation.align < 4096) {
7055 allocation.align = 4096;
7056 }
7057 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
7058 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7059 allocation.align, allocation.size);
7060 return false;
7061 }
7062 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007063}
David Ng38e2d232013-03-15 20:05:58 -07007064#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007065#ifdef USE_ION
7066int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007067 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7068 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007069{
Arun Menon906de572013-06-18 17:01:40 -07007070 int fd = -EINVAL;
7071 int rc = -EINVAL;
7072 int ion_dev_flag;
7073 struct vdec_ion ion_buf_info;
7074 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7075 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7076 return -EINVAL;
7077 }
7078 ion_dev_flag = O_RDONLY;
7079 fd = open (MEM_DEVICE, ion_dev_flag);
7080 if (fd < 0) {
7081 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7082 return fd;
7083 }
7084 alloc_data->flags = 0;
7085 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7086 alloc_data->flags |= ION_FLAG_CACHED;
7087 }
7088 alloc_data->len = buffer_size;
7089 alloc_data->align = clip2(alignment);
7090 if (alloc_data->align < 4096) {
7091 alloc_data->align = 4096;
7092 }
7093 if ((secure_mode) && (flag & ION_SECURE))
7094 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007095
Arun Menon906de572013-06-18 17:01:40 -07007096 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7097 if (secure_mode)
7098 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7099 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7100 if (rc || !alloc_data->handle) {
7101 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7102 alloc_data->handle = NULL;
7103 close(fd);
7104 fd = -ENOMEM;
7105 return fd;
7106 }
7107 fd_data->handle = alloc_data->handle;
7108 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7109 if (rc) {
7110 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7111 ion_buf_info.ion_alloc_data = *alloc_data;
7112 ion_buf_info.ion_device_fd = fd;
7113 ion_buf_info.fd_ion_data = *fd_data;
7114 free_ion_memory(&ion_buf_info);
7115 fd_data->fd =-1;
7116 close(fd);
7117 fd = -ENOMEM;
7118 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007119
Arun Menon906de572013-06-18 17:01:40 -07007120 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007121}
7122
Arun Menon906de572013-06-18 17:01:40 -07007123void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7124{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007125
Arun Menon906de572013-06-18 17:01:40 -07007126 if (!buf_ion_info) {
7127 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7128 return;
7129 }
7130 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7131 &buf_ion_info->ion_alloc_data.handle)) {
7132 DEBUG_PRINT_ERROR("\n ION: free failed" );
7133 }
7134 close(buf_ion_info->ion_device_fd);
7135 buf_ion_info->ion_device_fd = -1;
7136 buf_ion_info->ion_alloc_data.handle = NULL;
7137 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007138}
7139#endif
7140void omx_vdec::free_output_buffer_header()
7141{
Arun Menon906de572013-06-18 17:01:40 -07007142 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7143 output_use_buffer = false;
7144 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007145
Arun Menon906de572013-06-18 17:01:40 -07007146 if (m_out_mem_ptr) {
7147 free (m_out_mem_ptr);
7148 m_out_mem_ptr = NULL;
7149 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007150
Arun Menon906de572013-06-18 17:01:40 -07007151 if (m_platform_list) {
7152 free(m_platform_list);
7153 m_platform_list = NULL;
7154 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007155
Arun Menon906de572013-06-18 17:01:40 -07007156 if (drv_ctx.ptr_respbuffer) {
7157 free (drv_ctx.ptr_respbuffer);
7158 drv_ctx.ptr_respbuffer = NULL;
7159 }
7160 if (drv_ctx.ptr_outputbuffer) {
7161 free (drv_ctx.ptr_outputbuffer);
7162 drv_ctx.ptr_outputbuffer = NULL;
7163 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007164#ifdef USE_ION
7165 if (drv_ctx.op_buf_ion_info) {
7166 DEBUG_PRINT_LOW("\n Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007167 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007168 drv_ctx.op_buf_ion_info = NULL;
7169 }
7170#endif
7171}
7172
7173void omx_vdec::free_input_buffer_header()
7174{
7175 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007176 if (arbitrary_bytes) {
7177 if (m_frame_parser.mutils) {
7178 DEBUG_PRINT_LOW("\n Free utils parser");
7179 delete (m_frame_parser.mutils);
7180 m_frame_parser.mutils = NULL;
7181 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007182
Arun Menon906de572013-06-18 17:01:40 -07007183 if (m_inp_heap_ptr) {
7184 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7185 free (m_inp_heap_ptr);
7186 m_inp_heap_ptr = NULL;
7187 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007188
Arun Menon906de572013-06-18 17:01:40 -07007189 if (m_phdr_pmem_ptr) {
7190 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7191 free (m_phdr_pmem_ptr);
7192 m_phdr_pmem_ptr = NULL;
7193 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007194 }
Arun Menon906de572013-06-18 17:01:40 -07007195 if (m_inp_mem_ptr) {
7196 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7197 free (m_inp_mem_ptr);
7198 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007199 }
Arun Menon906de572013-06-18 17:01:40 -07007200 if (drv_ctx.ptr_inputbuffer) {
7201 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7202 free (drv_ctx.ptr_inputbuffer);
7203 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007204 }
7205#ifdef USE_ION
7206 if (drv_ctx.ip_buf_ion_info) {
7207 DEBUG_PRINT_LOW("\n Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007208 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007209 drv_ctx.ip_buf_ion_info = NULL;
7210 }
7211#endif
7212}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007213
7214int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007215{
Arun Menon906de572013-06-18 17:01:40 -07007216 enum v4l2_buf_type btype;
7217 int rc = 0;
7218 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007219
Arun Menon906de572013-06-18 17:01:40 -07007220 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7221 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7222 v4l2_port = OUTPUT_PORT;
7223 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7224 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7225 v4l2_port = CAPTURE_PORT;
7226 } else if (port == OMX_ALL) {
7227 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7228 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007229
Arun Menon906de572013-06-18 17:01:40 -07007230 if (!rc_input)
7231 return rc_input;
7232 else
7233 return rc_output;
7234 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007235
Arun Menon906de572013-06-18 17:01:40 -07007236 if (!streaming[v4l2_port]) {
7237 // already streamed off, warn and move on
7238 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7239 " which is already streamed off", v4l2_port);
7240 return 0;
7241 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007242
Arun Menon906de572013-06-18 17:01:40 -07007243 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007244
Arun Menon906de572013-06-18 17:01:40 -07007245 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7246 if (rc) {
7247 /*TODO: How to handle this case */
7248 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
7249 } else {
7250 streaming[v4l2_port] = false;
7251 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007252
Arun Menon906de572013-06-18 17:01:40 -07007253 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007254}
7255
7256OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7257{
Arun Menon906de572013-06-18 17:01:40 -07007258 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7259 struct v4l2_requestbuffers bufreq;
7260 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7261 struct v4l2_format fmt;
7262 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007263 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007264 buffer_prop->actualcount, buffer_prop->buffer_size);
7265 bufreq.memory = V4L2_MEMORY_USERPTR;
7266 bufreq.count = 1;
7267 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7268 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7269 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7270 fmt.fmt.pix_mp.pixelformat = output_capability;
7271 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7272 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7273 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7274 fmt.fmt.pix_mp.pixelformat = capture_capability;
7275 } else {
7276 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007277 }
Arun Menon906de572013-06-18 17:01:40 -07007278 if (eRet==OMX_ErrorNone) {
7279 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007280 }
Arun Menon906de572013-06-18 17:01:40 -07007281 if (ret) {
7282 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7283 /*TODO: How to handle this case */
7284 eRet = OMX_ErrorInsufficientResources;
7285 return eRet;
7286 } else {
7287 buffer_prop->actualcount = bufreq.count;
7288 buffer_prop->mincount = bufreq.count;
7289 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007290 }
Arun Menon906de572013-06-18 17:01:40 -07007291 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7292 buffer_prop->actualcount, buffer_prop->buffer_size);
7293
7294 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7295 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7296
7297 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7298
7299 update_resolution(fmt.fmt.pix_mp.width,
7300 fmt.fmt.pix_mp.height,
7301 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7302 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7303 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7304 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
7305 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
7306
7307 if (ret) {
7308 /*TODO: How to handle this case */
7309 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7310 eRet = OMX_ErrorInsufficientResources;
7311 } else {
7312 int extra_idx = 0;
7313
7314 eRet = is_video_session_supported();
7315 if (eRet)
7316 return eRet;
7317
7318 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7319 buf_size = buffer_prop->buffer_size;
7320 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7321 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7322 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7323 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7324 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7325 return OMX_ErrorBadParameter;
7326 }
7327 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7328 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7329 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7330 }
7331 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7332 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7333 }
7334 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7335 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7336 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7337 client_extra_data_size);
7338 }
7339 if (client_extra_data_size) {
7340 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7341 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7342 }
7343 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7344 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7345 drv_ctx.extradata_info.buffer_size = extra_data_size;
7346 buf_size += client_extra_data_size;
7347 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7348 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7349 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7350 if (in_reconfig) // BufReq will be set to driver when port is disabled
7351 buffer_prop->buffer_size = buf_size;
7352 else if (buf_size != buffer_prop->buffer_size) {
7353 buffer_prop->buffer_size = buf_size;
7354 eRet = set_buffer_req(buffer_prop);
7355 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007356 }
Arun Menon906de572013-06-18 17:01:40 -07007357 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7358 buffer_prop->actualcount, buffer_prop->buffer_size);
7359 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007360}
7361
7362OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7363{
Arun Menon906de572013-06-18 17:01:40 -07007364 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7365 unsigned buf_size = 0;
7366 struct v4l2_format fmt;
7367 struct v4l2_requestbuffers bufreq;
7368 int ret;
7369 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7370 buffer_prop->actualcount, buffer_prop->buffer_size);
7371 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7372 if (buf_size != buffer_prop->buffer_size) {
7373 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7374 buffer_prop->buffer_size, buf_size);
7375 eRet = OMX_ErrorBadParameter;
7376 } else {
7377 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7378 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007379
Arun Menon906de572013-06-18 17:01:40 -07007380 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7381 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7382 fmt.fmt.pix_mp.pixelformat = output_capability;
7383 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7384 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7385 fmt.fmt.pix_mp.pixelformat = capture_capability;
7386 } else {
7387 eRet = OMX_ErrorBadParameter;
7388 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007389
Arun Menon906de572013-06-18 17:01:40 -07007390 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7391 if (ret) {
7392 /*TODO: How to handle this case */
7393 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7394 eRet = OMX_ErrorInsufficientResources;
7395 }
7396
7397 bufreq.memory = V4L2_MEMORY_USERPTR;
7398 bufreq.count = buffer_prop->actualcount;
7399 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7400 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7401 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7402 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7403 } else {
7404 eRet = OMX_ErrorBadParameter;
7405 }
7406
7407 if (eRet==OMX_ErrorNone) {
7408 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7409 }
7410
7411 if (ret) {
7412 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7413 /*TODO: How to handle this case */
7414 eRet = OMX_ErrorInsufficientResources;
7415 } else if (bufreq.count < buffer_prop->actualcount) {
7416 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7417 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7418 buffer_prop->actualcount, bufreq.count);
7419 eRet = OMX_ErrorInsufficientResources;
7420 } else {
7421 if (!client_buffers.update_buffer_req()) {
7422 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7423 eRet = OMX_ErrorInsufficientResources;
7424 }
7425 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007426 }
Arun Menon906de572013-06-18 17:01:40 -07007427 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007428}
7429
Shalaj Jain273b3e02012-06-22 19:08:03 -07007430OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7431{
Arun Menon906de572013-06-18 17:01:40 -07007432 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7433 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007434}
7435
7436OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7437{
Arun Menon906de572013-06-18 17:01:40 -07007438 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7439 if (!portDefn) {
7440 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007441 }
Arun Menon906de572013-06-18 17:01:40 -07007442 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
7443 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7444 portDefn->nSize = sizeof(portDefn);
7445 portDefn->eDomain = OMX_PortDomainVideo;
7446 if (drv_ctx.frame_rate.fps_denominator > 0)
7447 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7448 drv_ctx.frame_rate.fps_denominator;
7449 else {
7450 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7451 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007452 }
Arun Menon906de572013-06-18 17:01:40 -07007453 if (0 == portDefn->nPortIndex) {
7454 portDefn->eDir = OMX_DirInput;
7455 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7456 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7457 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7458 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7459 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7460 portDefn->bEnabled = m_inp_bEnabled;
7461 portDefn->bPopulated = m_inp_bPopulated;
7462 } else if (1 == portDefn->nPortIndex) {
7463 unsigned int buf_size = 0;
7464 if (!client_buffers.update_buffer_req()) {
7465 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
7466 return OMX_ErrorHardware;
7467 }
7468 if (!client_buffers.get_buffer_req(buf_size)) {
7469 DEBUG_PRINT_ERROR("\n update buffer requirements");
7470 return OMX_ErrorHardware;
7471 }
7472 portDefn->nBufferSize = buf_size;
7473 portDefn->eDir = OMX_DirOutput;
7474 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7475 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7476 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7477 portDefn->bEnabled = m_out_bEnabled;
7478 portDefn->bPopulated = m_out_bPopulated;
7479 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
7480 DEBUG_PRINT_ERROR("\n Error in getting color format");
7481 return OMX_ErrorHardware;
7482 }
7483 } else {
7484 portDefn->eDir = OMX_DirMax;
7485 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7486 (int)portDefn->nPortIndex);
7487 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007488 }
Arun Menon906de572013-06-18 17:01:40 -07007489 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7490 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7491 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7492 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7493 DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
7494 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
7495 portDefn->format.video.nFrameHeight,
7496 portDefn->format.video.nStride,
7497 portDefn->format.video.nSliceHeight);
7498 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007499
7500}
7501
7502OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7503{
Arun Menon906de572013-06-18 17:01:40 -07007504 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7505 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7506 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007507
Arun Menon906de572013-06-18 17:01:40 -07007508 if (!m_out_mem_ptr) {
7509 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
7510 int nBufHdrSize = 0;
7511 int nPlatformEntrySize = 0;
7512 int nPlatformListSize = 0;
7513 int nPMEMInfoSize = 0;
7514 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7515 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7516 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007517
Arun Menon906de572013-06-18 17:01:40 -07007518 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
7519 drv_ctx.op_buf.actualcount);
7520 nBufHdrSize = drv_ctx.op_buf.actualcount *
7521 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007522
Arun Menon906de572013-06-18 17:01:40 -07007523 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7524 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7525 nPlatformListSize = drv_ctx.op_buf.actualcount *
7526 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7527 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7528 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007529
Arun Menon906de572013-06-18 17:01:40 -07007530 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
7531 sizeof(OMX_BUFFERHEADERTYPE),
7532 nPMEMInfoSize,
7533 nPlatformListSize);
7534 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
7535 m_out_bm_count);
7536 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7537 // Alloc mem for platform specific info
7538 char *pPtr=NULL;
7539 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7540 nPMEMInfoSize,1);
7541 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7542 calloc (sizeof(struct vdec_bufferpayload),
7543 drv_ctx.op_buf.actualcount);
7544 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7545 calloc (sizeof (struct vdec_output_frameinfo),
7546 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007547#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007548 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7549 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007550#endif
7551
Arun Menon906de572013-06-18 17:01:40 -07007552 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7553 && drv_ctx.ptr_respbuffer) {
7554 bufHdr = m_out_mem_ptr;
7555 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7556 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7557 (((char *) m_platform_list) + nPlatformListSize);
7558 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7559 (((char *) m_platform_entry) + nPlatformEntrySize);
7560 pPlatformList = m_platform_list;
7561 pPlatformEntry = m_platform_entry;
7562 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007563
Arun Menon906de572013-06-18 17:01:40 -07007564 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007565
Arun Menon906de572013-06-18 17:01:40 -07007566 // Settting the entire storage nicely
7567 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
7568 m_out_mem_ptr,pPlatformEntry);
7569 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
7570 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7571 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7572 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7573 // Set the values when we determine the right HxW param
7574 bufHdr->nAllocLen = 0;
7575 bufHdr->nFilledLen = 0;
7576 bufHdr->pAppPrivate = NULL;
7577 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7578 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7579 pPlatformEntry->entry = pPMEMInfo;
7580 // Initialize the Platform List
7581 pPlatformList->nEntries = 1;
7582 pPlatformList->entryList = pPlatformEntry;
7583 // Keep pBuffer NULL till vdec is opened
7584 bufHdr->pBuffer = NULL;
7585 pPMEMInfo->offset = 0;
7586 pPMEMInfo->pmem_fd = 0;
7587 bufHdr->pPlatformPrivate = pPlatformList;
7588 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007589#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007590 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007591#endif
Arun Menon906de572013-06-18 17:01:40 -07007592 /*Create a mapping between buffers*/
7593 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7594 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7595 &drv_ctx.ptr_outputbuffer[i];
7596 // Move the buffer and buffer header pointers
7597 bufHdr++;
7598 pPMEMInfo++;
7599 pPlatformEntry++;
7600 pPlatformList++;
7601 }
7602 } else {
7603 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
7604 m_out_mem_ptr, pPtr);
7605 if (m_out_mem_ptr) {
7606 free(m_out_mem_ptr);
7607 m_out_mem_ptr = NULL;
7608 }
7609 if (pPtr) {
7610 free(pPtr);
7611 pPtr = NULL;
7612 }
7613 if (drv_ctx.ptr_outputbuffer) {
7614 free(drv_ctx.ptr_outputbuffer);
7615 drv_ctx.ptr_outputbuffer = NULL;
7616 }
7617 if (drv_ctx.ptr_respbuffer) {
7618 free(drv_ctx.ptr_respbuffer);
7619 drv_ctx.ptr_respbuffer = NULL;
7620 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007621#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007622 if (drv_ctx.op_buf_ion_info) {
7623 DEBUG_PRINT_LOW("\n Free o/p ion context");
7624 free(drv_ctx.op_buf_ion_info);
7625 drv_ctx.op_buf_ion_info = NULL;
7626 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007627#endif
Arun Menon906de572013-06-18 17:01:40 -07007628 eRet = OMX_ErrorInsufficientResources;
7629 }
7630 } else {
7631 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007632 }
Arun Menon906de572013-06-18 17:01:40 -07007633 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007634}
7635
7636void omx_vdec::complete_pending_buffer_done_cbs()
7637{
Arun Menon906de572013-06-18 17:01:40 -07007638 unsigned p1;
7639 unsigned p2;
7640 unsigned ident;
7641 omx_cmd_queue tmp_q, pending_bd_q;
7642 pthread_mutex_lock(&m_lock);
7643 // pop all pending GENERATE FDB from ftb queue
7644 while (m_ftb_q.m_size) {
7645 m_ftb_q.pop_entry(&p1,&p2,&ident);
7646 if (ident == OMX_COMPONENT_GENERATE_FBD) {
7647 pending_bd_q.insert_entry(p1,p2,ident);
7648 } else {
7649 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007650 }
Arun Menon906de572013-06-18 17:01:40 -07007651 }
7652 //return all non GENERATE FDB to ftb queue
7653 while (tmp_q.m_size) {
7654 tmp_q.pop_entry(&p1,&p2,&ident);
7655 m_ftb_q.insert_entry(p1,p2,ident);
7656 }
7657 // pop all pending GENERATE EDB from etb queue
7658 while (m_etb_q.m_size) {
7659 m_etb_q.pop_entry(&p1,&p2,&ident);
7660 if (ident == OMX_COMPONENT_GENERATE_EBD) {
7661 pending_bd_q.insert_entry(p1,p2,ident);
7662 } else {
7663 tmp_q.insert_entry(p1,p2,ident);
7664 }
7665 }
7666 //return all non GENERATE FDB to etb queue
7667 while (tmp_q.m_size) {
7668 tmp_q.pop_entry(&p1,&p2,&ident);
7669 m_etb_q.insert_entry(p1,p2,ident);
7670 }
7671 pthread_mutex_unlock(&m_lock);
7672 // process all pending buffer dones
7673 while (pending_bd_q.m_size) {
7674 pending_bd_q.pop_entry(&p1,&p2,&ident);
7675 switch (ident) {
7676 case OMX_COMPONENT_GENERATE_EBD:
7677 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
7678 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
7679 omx_report_error ();
7680 }
7681 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007682
Arun Menon906de572013-06-18 17:01:40 -07007683 case OMX_COMPONENT_GENERATE_FBD:
7684 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
7685 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
7686 omx_report_error ();
7687 }
7688 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007689 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007690 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007691}
7692
7693void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
7694{
Arun Menon906de572013-06-18 17:01:40 -07007695 OMX_U32 new_frame_interval = 0;
7696 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
7697 && llabs(act_timestamp - prev_ts) > 2000) {
7698 new_frame_interval = client_set_fps ? frm_int :
7699 llabs(act_timestamp - prev_ts);
7700 if (new_frame_interval < frm_int || frm_int == 0) {
7701 frm_int = new_frame_interval;
7702 if (frm_int) {
7703 drv_ctx.frame_rate.fps_numerator = 1e6;
7704 drv_ctx.frame_rate.fps_denominator = frm_int;
7705 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
7706 frm_int, drv_ctx.frame_rate.fps_numerator /
7707 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007708
Arun Menon906de572013-06-18 17:01:40 -07007709 /* We need to report the difference between this FBD and the previous FBD
7710 * back to the driver for clock scaling purposes. */
7711 struct v4l2_outputparm oparm;
7712 /*XXX: we're providing timing info as seconds per frame rather than frames
7713 * per second.*/
7714 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
7715 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007716
Arun Menon906de572013-06-18 17:01:40 -07007717 struct v4l2_streamparm sparm;
7718 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7719 sparm.parm.output = oparm;
7720 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
7721 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
7722 performance might be affected");
7723 }
7724
7725 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007726 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007727 }
Arun Menon906de572013-06-18 17:01:40 -07007728 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007729}
7730
7731void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
7732{
Arun Menon906de572013-06-18 17:01:40 -07007733 if (rst_prev_ts && VALID_TS(act_timestamp)) {
7734 prev_ts = act_timestamp;
7735 rst_prev_ts = false;
7736 } else if (VALID_TS(prev_ts)) {
7737 bool codec_cond = (drv_ctx.timestamp_adjust)?
7738 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
7739 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
7740 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
7741 if (frm_int > 0 && codec_cond) {
7742 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
7743 act_timestamp = prev_ts + frm_int;
7744 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
7745 prev_ts = act_timestamp;
7746 } else
7747 set_frame_rate(act_timestamp);
7748 } else if (frm_int > 0) // In this case the frame rate was set along
7749 { // with the port definition, start ts with 0
7750 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
7751 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007752 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007753}
7754
7755void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
7756{
Arun Menon906de572013-06-18 17:01:40 -07007757 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
7758 OMX_U32 num_conceal_MB = 0;
7759 OMX_U32 frame_rate = 0;
7760 int consumed_len = 0;
7761 OMX_U32 num_MB_in_frame;
7762 OMX_U32 recovery_sei_flags = 1;
7763 int enable = 0;
7764 OMX_U32 mbaff = 0;
7765 int buf_index = p_buf_hdr - m_out_mem_ptr;
7766 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
7767 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
7768 p_buf_hdr->nOffset;
7769 if (!drv_ctx.extradata_info.uaddr) {
7770 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007771 }
Arun Menon906de572013-06-18 17:01:40 -07007772 p_extra = (OMX_OTHER_EXTRADATATYPE *)
7773 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
7774 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
7775 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
7776 p_extra = NULL;
7777 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
7778 if (data) {
7779 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
7780 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
7781 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
7782 DEBUG_PRINT_LOW("Invalid extra data size");
7783 break;
7784 }
7785 switch ((unsigned long)data->eType) {
7786 case EXTRADATA_INTERLACE_VIDEO:
7787 struct msm_vidc_interlace_payload *payload;
7788 payload = (struct msm_vidc_interlace_payload *)data->data;
7789 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
7790 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
7791 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
7792 else {
7793 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
7794 enable = 1;
7795 }
7796 if (m_enable_android_native_buffers)
7797 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
7798 PP_PARAM_INTERLACED, (void*)&enable);
7799 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
7800 append_interlace_extradata(p_extra, payload->format);
7801 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
7802 }
7803 break;
7804 case EXTRADATA_FRAME_RATE:
7805 struct msm_vidc_framerate_payload *frame_rate_payload;
7806 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
7807 frame_rate = frame_rate_payload->frame_rate;
7808 break;
7809 case EXTRADATA_TIMESTAMP:
7810 struct msm_vidc_ts_payload *time_stamp_payload;
7811 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
7812 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
7813 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
7814 break;
7815 case EXTRADATA_NUM_CONCEALED_MB:
7816 struct msm_vidc_concealmb_payload *conceal_mb_payload;
7817 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
7818 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
7819 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
7820 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
7821 break;
7822 case EXTRADATA_INDEX:
7823 int *etype;
7824 etype = (int *)(data->data);
7825 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
7826 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
7827 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
7828 if (aspect_ratio_payload) {
7829 ((struct vdec_output_frameinfo *)
7830 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
7831 ((struct vdec_output_frameinfo *)
7832 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
7833 }
7834 }
7835 break;
7836 case EXTRADATA_RECOVERY_POINT_SEI:
7837 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
7838 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
7839 recovery_sei_flags = recovery_sei_payload->flags;
7840 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
7841 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7842 DEBUG_PRINT_HIGH("\n");
7843 DEBUG_PRINT_HIGH("***************************************************\n");
7844 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
7845 DEBUG_PRINT_HIGH("***************************************************\n");
7846 }
7847 break;
7848 case EXTRADATA_PANSCAN_WINDOW:
7849 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
7850 break;
7851 case EXTRADATA_MPEG2_SEQDISP:
7852 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
7853 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
7854 if (seqdisp_payload) {
7855 m_disp_hor_size = seqdisp_payload->disp_width;
7856 m_disp_vert_size = seqdisp_payload->disp_height;
7857 }
7858 break;
7859 default:
7860 goto unrecognized_extradata;
7861 }
7862 consumed_len += data->nSize;
7863 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
7864 }
7865 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
7866 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
7867 append_frame_info_extradata(p_extra,
7868 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
7869 panscan_payload,&((struct vdec_output_frameinfo *)
7870 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
7871 }
7872 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007873unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07007874 if (!secure_mode && client_extradata)
7875 append_terminator_extradata(p_extra);
7876 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007877}
7878
Vinay Kalia9c00cae2012-12-06 16:08:20 -08007879OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07007880 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007881{
Arun Menon906de572013-06-18 17:01:40 -07007882 OMX_ERRORTYPE ret = OMX_ErrorNone;
7883 struct v4l2_control control;
7884 if (m_state != OMX_StateLoaded) {
7885 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
7886 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08007887 }
Arun Menon906de572013-06-18 17:01:40 -07007888 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
7889 client_extradata, requested_extradata, enable, is_internal);
7890
7891 if (!is_internal) {
7892 if (enable)
7893 client_extradata |= requested_extradata;
7894 else
7895 client_extradata = client_extradata & ~requested_extradata;
7896 }
7897
7898 if (enable) {
7899 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
7900 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7901 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
7902 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7903 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
7904 " Quality of interlaced clips might be impacted.\n");
7905 }
7906 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
7907 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7908 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
7909 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7910 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
7911 }
7912 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7913 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
7914 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7915 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
7916 }
7917 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7918 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
7919 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7920 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
7921 }
7922 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7923 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
7924 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7925 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7926 }
7927 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7928 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
7929 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7930 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7931 }
7932 if (output_capability == V4L2_PIX_FMT_MPEG2) {
7933 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7934 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
7935 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7936 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7937 }
7938 }
7939 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
7940 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7941 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
7942 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7943 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
7944 }
7945 }
7946 }
7947 ret = get_buffer_req(&drv_ctx.op_buf);
7948 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007949}
7950
7951OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
7952{
Arun Menon906de572013-06-18 17:01:40 -07007953 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
7954 OMX_U8 *data_ptr = extra->data, data = 0;
7955 while (byte_count < extra->nDataSize) {
7956 data = *data_ptr;
7957 while (data) {
7958 num_MB += (data&0x01);
7959 data >>= 1;
7960 }
7961 data_ptr++;
7962 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007963 }
Arun Menon906de572013-06-18 17:01:40 -07007964 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
7965 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
7966 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007967}
7968
7969void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
7970{
Arun Menon906de572013-06-18 17:01:40 -07007971 if (!m_debug_extradata)
7972 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007973
7974 DEBUG_PRINT_HIGH(
Arun Menon906de572013-06-18 17:01:40 -07007975 "============== Extra Data ==============\n"
7976 " Size: %lu \n"
7977 " Version: %lu \n"
7978 " PortIndex: %lu \n"
7979 " Type: %x \n"
7980 " DataSize: %lu \n",
7981 extra->nSize, extra->nVersion.nVersion,
7982 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007983
Arun Menon906de572013-06-18 17:01:40 -07007984 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
7985 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
7986 DEBUG_PRINT_HIGH(
7987 "------ Interlace Format ------\n"
7988 " Size: %lu \n"
7989 " Version: %lu \n"
7990 " PortIndex: %lu \n"
7991 " Is Interlace Format: %d \n"
7992 " Interlace Formats: %lu \n"
7993 "=========== End of Interlace ===========\n",
7994 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
7995 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
7996 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
7997 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
7998
7999 DEBUG_PRINT_HIGH(
8000 "-------- Frame Format --------\n"
8001 " Picture Type: %d \n"
8002 " Interlace Type: %d \n"
8003 " Pan Scan Total Frame Num: %lu \n"
8004 " Concealed Macro Blocks: %lu \n"
8005 " frame rate: %lu \n"
8006 " Aspect Ratio X: %lu \n"
8007 " Aspect Ratio Y: %lu \n",
8008 fminfo->ePicType,
8009 fminfo->interlaceType,
8010 fminfo->panScan.numWindows,
8011 fminfo->nConcealedMacroblocks,
8012 fminfo->nFrameRate,
8013 fminfo->aspectRatio.aspectRatioX,
8014 fminfo->aspectRatio.aspectRatioY);
8015
8016 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8017 DEBUG_PRINT_HIGH(
8018 "------------------------------\n"
8019 " Pan Scan Frame Num: %lu \n"
8020 " Rectangle x: %ld \n"
8021 " Rectangle y: %ld \n"
8022 " Rectangle dx: %ld \n"
8023 " Rectangle dy: %ld \n",
8024 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8025 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8026 }
8027
8028 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8029 } else if (extra->eType == OMX_ExtraDataNone) {
8030 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8031 } else {
8032 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008033 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008034}
8035
8036void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008037 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008038{
Arun Menon906de572013-06-18 17:01:40 -07008039 OMX_STREAMINTERLACEFORMAT *interlace_format;
8040 OMX_U32 mbaff = 0;
8041 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8042 return;
8043 }
8044 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8045 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8046 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8047 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8048 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8049 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8050 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8051 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8052 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8053 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8054 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8055 interlace_format->bInterlaceFormat = OMX_FALSE;
8056 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8057 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8058 } else {
8059 interlace_format->bInterlaceFormat = OMX_TRUE;
8060 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8061 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8062 }
8063 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008064}
8065
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008066void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008067 struct vdec_aspectratioinfo *aspect_ratio_info,
8068 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008069{
Arun Menon906de572013-06-18 17:01:40 -07008070 m_extradata = frame_info;
8071 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8072 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
8073 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
8074 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008075}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008076
8077void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008078 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008079 struct msm_vidc_panscan_window_payload *panscan_payload,
8080 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008081{
Arun Menon906de572013-06-18 17:01:40 -07008082 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8083 struct msm_vidc_panscan_window *panscan_window;
8084 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008085 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008086 }
Arun Menon906de572013-06-18 17:01:40 -07008087 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8088 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8089 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8090 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8091 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8092 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8093 switch (picture_type) {
8094 case PICTURE_TYPE_I:
8095 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8096 break;
8097 case PICTURE_TYPE_P:
8098 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8099 break;
8100 case PICTURE_TYPE_B:
8101 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8102 break;
8103 default:
8104 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8105 }
8106 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8107 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8108 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8109 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8110 else
8111 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8112 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8113 frame_info->nConcealedMacroblocks = num_conceal_mb;
8114 frame_info->nFrameRate = frame_rate;
8115 frame_info->panScan.numWindows = 0;
8116 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8117 if (m_disp_hor_size && m_disp_vert_size) {
8118 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8119 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8120 }
8121 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008122
Arun Menon906de572013-06-18 17:01:40 -07008123 if (panscan_payload) {
8124 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8125 panscan_window = &panscan_payload->wnd[0];
8126 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8127 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8128 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8129 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8130 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8131 panscan_window++;
8132 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008133 }
Arun Menon906de572013-06-18 17:01:40 -07008134 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8135 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008136}
8137
8138void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8139{
Arun Menon906de572013-06-18 17:01:40 -07008140 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8141 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8142 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8143 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8144 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8145 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8146 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8147 *portDefn = m_port_def;
8148 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8149 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
8150 portDefn->format.video.nFrameWidth,
8151 portDefn->format.video.nStride,
8152 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008153}
8154
8155void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8156{
Arun Menon906de572013-06-18 17:01:40 -07008157 if (!client_extradata) {
8158 return;
8159 }
8160 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8161 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8162 extra->eType = OMX_ExtraDataNone;
8163 extra->nDataSize = 0;
8164 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008165
Arun Menon906de572013-06-18 17:01:40 -07008166 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008167}
8168
8169OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8170{
Arun Menon906de572013-06-18 17:01:40 -07008171 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8172 if (index >= drv_ctx.ip_buf.actualcount) {
8173 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8174 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008175 }
Arun Menon906de572013-06-18 17:01:40 -07008176 if (m_desc_buffer_ptr == NULL) {
8177 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8178 calloc( (sizeof(desc_buffer_hdr)),
8179 drv_ctx.ip_buf.actualcount);
8180 if (m_desc_buffer_ptr == NULL) {
8181 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8182 return OMX_ErrorInsufficientResources;
8183 }
8184 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008185
Arun Menon906de572013-06-18 17:01:40 -07008186 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8187 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
8188 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8189 return OMX_ErrorInsufficientResources;
8190 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008191
Arun Menon906de572013-06-18 17:01:40 -07008192 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008193}
8194
8195void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8196{
Arun Menon906de572013-06-18 17:01:40 -07008197 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8198 if (m_demux_entries < 8192) {
8199 m_demux_offsets[m_demux_entries++] = address_offset;
8200 }
8201 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008202}
8203
8204void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8205{
Arun Menon906de572013-06-18 17:01:40 -07008206 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8207 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8208 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008209
Arun Menon906de572013-06-18 17:01:40 -07008210 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008211
Arun Menon906de572013-06-18 17:01:40 -07008212 while (index < bytes_to_parse) {
8213 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8214 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8215 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8216 (buf[index+2] == 0x01)) ) {
8217 //Found start code, insert address offset
8218 insert_demux_addr_offset(index);
8219 if (buf[index+2] == 0x01) // 3 byte start code
8220 index += 3;
8221 else //4 byte start code
8222 index += 4;
8223 } else
8224 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008225 }
Arun Menon906de572013-06-18 17:01:40 -07008226 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8227 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008228}
8229
8230OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8231{
Arun Menon906de572013-06-18 17:01:40 -07008232 //fix this, handle 3 byte start code, vc1 terminator entry
8233 OMX_U8 *p_demux_data = NULL;
8234 OMX_U32 desc_data = 0;
8235 OMX_U32 start_addr = 0;
8236 OMX_U32 nal_size = 0;
8237 OMX_U32 suffix_byte = 0;
8238 OMX_U32 demux_index = 0;
8239 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008240
Arun Menon906de572013-06-18 17:01:40 -07008241 if (m_desc_buffer_ptr == NULL) {
8242 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8243 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008244 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008245
Arun Menon906de572013-06-18 17:01:40 -07008246 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8247 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8248 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8249 return OMX_ErrorBadParameter;
8250 }
8251
8252 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8253
8254 if ( ((OMX_U8*)p_demux_data == NULL) ||
8255 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8256 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8257 return OMX_ErrorBadParameter;
8258 } else {
8259 for (; demux_index < m_demux_entries; demux_index++) {
8260 desc_data = 0;
8261 start_addr = m_demux_offsets[demux_index];
8262 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8263 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8264 } else {
8265 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8266 }
8267 if (demux_index < (m_demux_entries - 1)) {
8268 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8269 } else {
8270 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8271 }
8272 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8273 (void *)start_addr,
8274 suffix_byte,
8275 nal_size,
8276 demux_index);
8277 desc_data = (start_addr >> 3) << 1;
8278 desc_data |= (start_addr & 7) << 21;
8279 desc_data |= suffix_byte << 24;
8280
8281 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8282 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8283 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8284 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8285
8286 p_demux_data += 16;
8287 }
8288 if (codec_type_parse == CODEC_TYPE_VC1) {
8289 DEBUG_PRINT_LOW("VC1 terminator entry");
8290 desc_data = 0;
8291 desc_data = 0x82 << 24;
8292 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8293 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8294 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8295 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8296 p_demux_data += 16;
8297 m_demux_entries++;
8298 }
8299 //Add zero word to indicate end of descriptors
8300 memset(p_demux_data, 0, sizeof(OMX_U32));
8301
8302 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8303 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8304 }
8305 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8306 m_demux_entries = 0;
8307 DEBUG_PRINT_LOW("Demux table complete!");
8308 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008309}
8310
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008311OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008312{
Arun Menon906de572013-06-18 17:01:40 -07008313 OMX_ERRORTYPE err = OMX_ErrorNone;
8314 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8315 if (iDivXDrmDecrypt) {
8316 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8317 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008318 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008319 delete iDivXDrmDecrypt;
8320 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008321 }
8322 } else {
8323 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
8324 err = OMX_ErrorUndefined;
8325 }
8326 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008327}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008328
Vinay Kaliada4f4422013-01-09 10:45:03 -08008329omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8330{
Arun Menon906de572013-06-18 17:01:40 -07008331 enabled = false;
8332 omx = NULL;
8333 init_members();
8334 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008335}
8336
8337void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8338{
Arun Menon906de572013-06-18 17:01:40 -07008339 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008340}
8341
Arun Menon906de572013-06-18 17:01:40 -07008342void omx_vdec::allocate_color_convert_buf::init_members()
8343{
8344 allocated_count = 0;
8345 buffer_size_req = 0;
8346 buffer_alignment_req = 0;
8347 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8348 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8349 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8350 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008351#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008352 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008353#endif
Arun Menon906de572013-06-18 17:01:40 -07008354 for (int i = 0; i < MAX_COUNT; i++)
8355 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008356}
8357
Arun Menon906de572013-06-18 17:01:40 -07008358omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8359{
8360 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008361}
8362
8363bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8364{
Arun Menon906de572013-06-18 17:01:40 -07008365 bool status = true;
8366 unsigned int src_size = 0, destination_size = 0;
8367 OMX_COLOR_FORMATTYPE drv_color_format;
8368 if (!omx) {
8369 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8370 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008371 }
Arun Menon906de572013-06-18 17:01:40 -07008372 if (!enabled) {
8373 DEBUG_PRINT_HIGH("\n No color conversion required");
8374 return status;
8375 }
8376 pthread_mutex_lock(&omx->c_lock);
8377 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8378 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8379 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
8380 status = false;
8381 goto fail_update_buf_req;
8382 }
8383 c2d.close();
8384 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8385 omx->drv_ctx.video_resolution.frame_width,
8386 NV12_128m,YCbCr420P);
8387 if (status) {
8388 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8389 if (status)
8390 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8391 }
8392 if (status) {
8393 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8394 !destination_size) {
8395 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
8396 "driver size %d destination size %d",
8397 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8398 status = false;
8399 c2d.close();
8400 buffer_size_req = 0;
8401 } else {
8402 buffer_size_req = destination_size;
8403 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8404 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8405 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8406 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8407 }
8408 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008409fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008410 pthread_mutex_unlock(&omx->c_lock);
8411 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008412}
8413
8414bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008415 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008416{
Arun Menon906de572013-06-18 17:01:40 -07008417 bool status = true;
8418 OMX_COLOR_FORMATTYPE drv_color_format;
8419 if (!omx) {
8420 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8421 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008422 }
Arun Menon906de572013-06-18 17:01:40 -07008423 pthread_mutex_lock(&omx->c_lock);
8424 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8425 drv_color_format = (OMX_COLOR_FORMATTYPE)
8426 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8427 else {
8428 DEBUG_PRINT_ERROR("\n Incorrect color format");
8429 status = false;
8430 }
8431 if (status && (drv_color_format != dest_color_format)) {
8432 DEBUG_PRINT_LOW("Enabling C2D\n");
8433 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
8434 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
8435 status = false;
8436 } else {
8437 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8438 if (enabled)
8439 c2d.destroy();
8440 enabled = false;
8441 if (!c2d.init()) {
8442 DEBUG_PRINT_ERROR("\n open failed for c2d");
8443 status = false;
8444 } else
8445 enabled = true;
8446 }
8447 } else {
8448 if (enabled)
8449 c2d.destroy();
8450 enabled = false;
8451 }
8452 pthread_mutex_unlock(&omx->c_lock);
8453 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008454}
8455
8456OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8457{
Arun Menon906de572013-06-18 17:01:40 -07008458 if (!omx) {
8459 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8460 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008461 }
Arun Menon906de572013-06-18 17:01:40 -07008462 if (!enabled)
8463 return omx->m_out_mem_ptr;
8464 return m_out_mem_ptr_client;
8465}
8466
8467 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
8468(OMX_BUFFERHEADERTYPE *bufadd)
8469{
8470 if (!omx) {
8471 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8472 return NULL;
8473 }
8474 if (!enabled)
8475 return bufadd;
8476
8477 unsigned index = 0;
8478 index = bufadd - omx->m_out_mem_ptr;
8479 if (index < omx->drv_ctx.op_buf.actualcount) {
8480 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
8481 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
8482 bool status;
8483 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
8484 pthread_mutex_lock(&omx->c_lock);
8485 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
8486 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
8487 pmem_baseaddress[index], pmem_baseaddress[index]);
8488 pthread_mutex_unlock(&omx->c_lock);
8489 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
8490 if (!status) {
8491 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
8492 m_out_mem_ptr_client[index].nFilledLen = 0;
8493 return &m_out_mem_ptr_client[index];
8494 }
8495 } else
8496 m_out_mem_ptr_client[index].nFilledLen = 0;
8497 return &m_out_mem_ptr_client[index];
8498 }
8499 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
8500 return NULL;
8501}
8502
8503 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
8504(OMX_BUFFERHEADERTYPE *bufadd)
8505{
8506 if (!omx) {
8507 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8508 return NULL;
8509 }
8510 if (!enabled)
8511 return bufadd;
8512 unsigned index = 0;
8513 index = bufadd - m_out_mem_ptr_client;
8514 if (index < omx->drv_ctx.op_buf.actualcount) {
8515 return &omx->m_out_mem_ptr[index];
8516 }
8517 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
8518 return NULL;
8519}
8520 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
8521(unsigned int &buffer_size)
8522{
8523 bool status = true;
8524 pthread_mutex_lock(&omx->c_lock);
8525 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008526 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07008527 else {
8528 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
8529 DEBUG_PRINT_ERROR("\n Get buffer size failed");
8530 status = false;
8531 goto fail_get_buffer_size;
8532 }
8533 }
8534 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
8535 buffer_size = omx->drv_ctx.op_buf.buffer_size;
8536 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8537 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008538fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07008539 pthread_mutex_unlock(&omx->c_lock);
8540 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008541}
8542OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07008543 OMX_BUFFERHEADERTYPE *bufhdr)
8544{
8545 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008546
Arun Menon906de572013-06-18 17:01:40 -07008547 if (!enabled)
8548 return omx->free_output_buffer(bufhdr);
8549 if (enabled && omx->is_component_secure())
8550 return OMX_ErrorNone;
8551 if (!allocated_count || !bufhdr) {
8552 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
8553 return OMX_ErrorBadParameter;
8554 }
8555 index = bufhdr - m_out_mem_ptr_client;
8556 if (index >= omx->drv_ctx.op_buf.actualcount) {
8557 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
8558 return OMX_ErrorBadParameter;
8559 }
8560 if (pmem_fd[index] > 0) {
8561 munmap(pmem_baseaddress[index], buffer_size_req);
8562 close(pmem_fd[index]);
8563 }
8564 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008565#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008566 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008567#endif
Arun Menon906de572013-06-18 17:01:40 -07008568 m_heap_ptr[index].video_heap_ptr = NULL;
8569 if (allocated_count > 0)
8570 allocated_count--;
8571 else
8572 allocated_count = 0;
8573 if (!allocated_count) {
8574 pthread_mutex_lock(&omx->c_lock);
8575 c2d.close();
8576 init_members();
8577 pthread_mutex_unlock(&omx->c_lock);
8578 }
8579 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008580}
8581
8582OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07008583 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008584{
Arun Menon906de572013-06-18 17:01:40 -07008585 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8586 if (!enabled) {
8587 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
8588 return eRet;
8589 }
8590 if (enabled && omx->is_component_secure()) {
8591 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
8592 omx->is_component_secure());
8593 return OMX_ErrorUnsupportedSetting;
8594 }
8595 if (!bufferHdr || bytes > buffer_size_req) {
8596 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
8597 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
8598 buffer_size_req,bytes);
8599 return OMX_ErrorBadParameter;
8600 }
8601 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
8602 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
8603 return OMX_ErrorInsufficientResources;
8604 }
8605 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
8606 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
8607 port,appData,omx->drv_ctx.op_buf.buffer_size);
8608 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
8609 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
8610 return eRet;
8611 }
8612 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
8613 omx->drv_ctx.op_buf.actualcount) {
8614 DEBUG_PRINT_ERROR("\n Invalid header index %d",
8615 (temp_bufferHdr - omx->m_out_mem_ptr));
8616 return OMX_ErrorUndefined;
8617 }
8618 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008619#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008620 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
8621 buffer_size_req,buffer_alignment_req,
8622 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
8623 0);
8624 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
8625 if (op_buf_ion_info[i].ion_device_fd < 0) {
8626 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
8627 return OMX_ErrorInsufficientResources;
8628 }
8629 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
8630 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008631
Arun Menon906de572013-06-18 17:01:40 -07008632 if (pmem_baseaddress[i] == MAP_FAILED) {
8633 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
8634 close(pmem_fd[i]);
8635 omx->free_ion_memory(&op_buf_ion_info[i]);
8636 return OMX_ErrorInsufficientResources;
8637 }
8638 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
8639 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
8640 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008641#endif
Arun Menon906de572013-06-18 17:01:40 -07008642 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
8643 m_pmem_info_client[i].offset = 0;
8644 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
8645 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8646 m_platform_list_client[i].nEntries = 1;
8647 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
8648 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
8649 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
8650 m_out_mem_ptr_client[i].nFilledLen = 0;
8651 m_out_mem_ptr_client[i].nFlags = 0;
8652 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8653 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
8654 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
8655 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
8656 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
8657 m_out_mem_ptr_client[i].pAppPrivate = appData;
8658 *bufferHdr = &m_out_mem_ptr_client[i];
8659 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
8660 allocated_count++;
8661 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008662}
8663
8664bool omx_vdec::is_component_secure()
8665{
Arun Menon906de572013-06-18 17:01:40 -07008666 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008667}
8668
8669bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
8670{
Arun Menon906de572013-06-18 17:01:40 -07008671 bool status = true;
8672 if (!enabled) {
8673 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8674 dest_color_format = (OMX_COLOR_FORMATTYPE)
8675 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8676 else
8677 status = false;
8678 } else {
8679 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8680 status = false;
8681 } else
8682 dest_color_format = OMX_COLOR_FormatYUV420Planar;
8683 }
8684 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008685}