blob: bbff759c064f6abe3f9647e9bdd6d54102eb7ca5 [file] [log] [blame]
Shalaj Jain273b3e02012-06-22 19:08:03 -07001/*--------------------------------------------------------------------------
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -08002Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
Vinay Kaliae4a7d9d2013-01-21 10:16:33 -080011 * Neither the name of The Linux Foundation nor
Shalaj Jain273b3e02012-06-22 19:08:03 -070012 the names of its contributors may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27--------------------------------------------------------------------------*/
28
29/*============================================================================
30 O p e n M A X w r a p p e r s
31 O p e n M A X C o r e
32
33*//** @file omx_vdec.cpp
34 This module contains the implementation of the OpenMAX core & component.
35
36*//*========================================================================*/
37
38//////////////////////////////////////////////////////////////////////////////
39// Include Files
40//////////////////////////////////////////////////////////////////////////////
41
42#include <string.h>
43#include <pthread.h>
44#include <sys/prctl.h>
45#include <stdlib.h>
46#include <unistd.h>
47#include <errno.h>
48#include "omx_vdec.h"
49#include <fcntl.h>
50#include <limits.h>
Deva Ramasubramanian15bbc1c2013-05-13 16:05:03 -070051#include <stdlib.h>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080052#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070053
54#ifndef _ANDROID_
55#include <sys/ioctl.h>
56#include <sys/mman.h>
57#endif //_ANDROID_
58
59#ifdef _ANDROID_
60#include <cutils/properties.h>
61#undef USE_EGL_IMAGE_GPU
62#endif
63
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070064#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070065
66#ifdef _ANDROID_
67#include "DivXDrmDecrypt.h"
68#endif //_ANDROID_
69
70#ifdef USE_EGL_IMAGE_GPU
71#include <EGL/egl.h>
72#include <EGL/eglQCOM.h>
73#define EGL_BUFFER_HANDLE_QCOM 0x4F00
74#define EGL_BUFFER_OFFSET_QCOM 0x4F01
75#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -070076#ifdef INPUT_BUFFER_LOG
77#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0"
78#define INPUT_BUFFER_FILE_NAME_LEN 30
79FILE *inputBufferFile1;
80char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
81#endif
82#ifdef OUTPUT_BUFFER_LOG
83FILE *outputBufferFile1;
84char outputfilename [] = "/data/output.yuv";
Vinay Kalia21649b32013-03-18 17:28:07 -070085
Shalaj Jain273b3e02012-06-22 19:08:03 -070086#endif
87#ifdef OUTPUT_EXTRADATA_LOG
88FILE *outputExtradataFile;
89char ouputextradatafilename [] = "/data/extradata";
90#endif
91
92#define DEFAULT_FPS 30
93#define MAX_INPUT_ERROR DEFAULT_FPS
94#define MAX_SUPPORTED_FPS 120
95
96#define VC1_SP_MP_START_CODE 0xC5000000
97#define VC1_SP_MP_START_CODE_MASK 0xFF000000
98#define VC1_AP_SEQ_START_CODE 0x0F010000
99#define VC1_STRUCT_C_PROFILE_MASK 0xF0
100#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
101#define VC1_SIMPLE_PROFILE 0
102#define VC1_MAIN_PROFILE 1
103#define VC1_ADVANCE_PROFILE 3
104#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
105#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
106#define VC1_STRUCT_C_LEN 4
107#define VC1_STRUCT_C_POS 8
108#define VC1_STRUCT_A_POS 12
109#define VC1_STRUCT_B_POS 24
110#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700111#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700112
113#define MEM_DEVICE "/dev/ion"
114#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
115
116#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700117extern "C" {
118#include<utils/Log.h>
119}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700120#endif//_ANDROID_
121
Vinay Kalia53fa6832012-10-11 17:55:30 -0700122#define SZ_4K 0x1000
123#define SZ_1M 0x100000
124
Shalaj Jain273b3e02012-06-22 19:08:03 -0700125#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
126#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 -0700127#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
128
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800129#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700130
131int debug_level = PRIO_ERROR;
132
Shalaj Jain273b3e02012-06-22 19:08:03 -0700133void* async_message_thread (void *input)
134{
Arun Menon906de572013-06-18 17:01:40 -0700135 OMX_BUFFERHEADERTYPE *buffer;
136 struct v4l2_plane plane[VIDEO_MAX_PLANES];
137 struct pollfd pfd;
138 struct v4l2_buffer v4l2_buf;
139 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
140 struct v4l2_event dqevent;
141 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
142 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
143 pfd.fd = omx->drv_ctx.video_driver_fd;
144 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
145 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
146 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
147 while (1) {
148 rc = poll(&pfd, 1, POLL_TIMEOUT);
149 if (!rc) {
150 DEBUG_PRINT_ERROR("Poll timedout\n");
151 break;
152 } else if (rc < 0) {
153 DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
154 break;
155 }
156 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
157 struct vdec_msginfo vdec_msg;
158 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
159 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
160 v4l2_buf.length = omx->drv_ctx.num_planes;
161 v4l2_buf.m.planes = plane;
162 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
163 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
164 vdec_msg.status_code=VDEC_S_SUCCESS;
165 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
166 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
167 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
168 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
169 (uint64_t)v4l2_buf.timestamp.tv_usec;
170 if (vdec_msg.msgdata.output_frame.len) {
171 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
172 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
173 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
174 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
175 }
176 if (omx->async_message_process(input,&vdec_msg) < 0) {
177 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
178 break;
179 }
180 }
181 }
182 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
183 struct vdec_msginfo vdec_msg;
184 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
185 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
186 v4l2_buf.length = 1;
187 v4l2_buf.m.planes = plane;
188 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
189 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
190 vdec_msg.status_code=VDEC_S_SUCCESS;
191 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
192 if (omx->async_message_process(input,&vdec_msg) < 0) {
193 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
194 break;
195 }
196 }
197 }
198 if (pfd.revents & POLLPRI) {
199 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
200 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
201 struct vdec_msginfo vdec_msg;
202 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
203 vdec_msg.status_code=VDEC_S_SUCCESS;
204 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved insufficient\n");
205 if (omx->async_message_process(input,&vdec_msg) < 0) {
206 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
207 break;
208 }
209 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
210 struct vdec_msginfo vdec_msg;
211 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
212 vdec_msg.status_code=VDEC_S_SUCCESS;
213 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved \n");
214 if (omx->async_message_process(input,&vdec_msg) < 0) {
215 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
216 break;
217 }
218 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
219 vdec_msg.status_code=VDEC_S_SUCCESS;
220 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved \n");
221 if (omx->async_message_process(input,&vdec_msg) < 0) {
222 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
223 break;
224 }
225 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
226 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
227 break;
228 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
229 struct vdec_msginfo vdec_msg;
230 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
231 vdec_msg.status_code=VDEC_S_SUCCESS;
232 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
233 if (omx->async_message_process(input,&vdec_msg) < 0) {
234 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
235 break;
236 }
237 } else {
238 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
239 continue;
240 }
241 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700242 }
Arun Menon906de572013-06-18 17:01:40 -0700243 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
244 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700245}
246
247void* message_thread(void *input)
248{
Arun Menon906de572013-06-18 17:01:40 -0700249 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
250 unsigned char id;
251 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700252
Arun Menon906de572013-06-18 17:01:40 -0700253 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
254 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
255 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700256
Arun Menon906de572013-06-18 17:01:40 -0700257 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700258
Arun Menon906de572013-06-18 17:01:40 -0700259 if (0 == n) {
260 break;
261 }
262
263 if (1 == n) {
264 omx->process_event_cb(omx, id);
265 }
266 if ((n < 0) && (errno != EINTR)) {
267 DEBUG_PRINT_LOW("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
268 break;
269 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700270 }
Arun Menon906de572013-06-18 17:01:40 -0700271 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
272 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700273}
274
275void post_message(omx_vdec *omx, unsigned char id)
276{
Arun Menon906de572013-06-18 17:01:40 -0700277 int ret_value;
278 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
279 ret_value = write(omx->m_pipe_out, &id, 1);
280 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700281}
282
283// omx_cmd_queue destructor
284omx_vdec::omx_cmd_queue::~omx_cmd_queue()
285{
Arun Menon906de572013-06-18 17:01:40 -0700286 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700287}
288
289// omx cmd queue constructor
290omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
291{
292 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
293}
294
295// omx cmd queue insert
296bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
297{
Arun Menon906de572013-06-18 17:01:40 -0700298 bool ret = true;
299 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
300 m_q[m_write].id = id;
301 m_q[m_write].param1 = p1;
302 m_q[m_write].param2 = p2;
303 m_write++;
304 m_size ++;
305 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
306 m_write = 0;
307 }
308 } else {
309 ret = false;
310 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700311 }
Arun Menon906de572013-06-18 17:01:40 -0700312 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700313}
314
315// omx cmd queue pop
316bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
317{
Arun Menon906de572013-06-18 17:01:40 -0700318 bool ret = true;
319 if (m_size > 0) {
320 *id = m_q[m_read].id;
321 *p1 = m_q[m_read].param1;
322 *p2 = m_q[m_read].param2;
323 // Move the read pointer ahead
324 ++m_read;
325 --m_size;
326 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
327 m_read = 0;
328 }
329 } else {
330 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700331 }
Arun Menon906de572013-06-18 17:01:40 -0700332 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700333}
334
335// Retrieve the first mesg type in the queue
336unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
337{
338 return m_q[m_read].id;
339}
340
341#ifdef _ANDROID_
342omx_vdec::ts_arr_list::ts_arr_list()
343{
Arun Menon906de572013-06-18 17:01:40 -0700344 //initialize timestamps array
345 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700346}
347omx_vdec::ts_arr_list::~ts_arr_list()
348{
Arun Menon906de572013-06-18 17:01:40 -0700349 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700350}
351
352bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
353{
Arun Menon906de572013-06-18 17:01:40 -0700354 bool ret = true;
355 bool duplicate_ts = false;
356 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700357
Arun Menon906de572013-06-18 17:01:40 -0700358 //insert at the first available empty location
359 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
360 if (!m_ts_arr_list[idx].valid) {
361 //found invalid or empty entry, save timestamp
362 m_ts_arr_list[idx].valid = true;
363 m_ts_arr_list[idx].timestamp = ts;
364 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
365 ts, idx);
366 break;
367 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700368 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700369
Arun Menon906de572013-06-18 17:01:40 -0700370 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
371 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
372 ret = false;
373 }
374 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700375}
376
377bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
378{
Arun Menon906de572013-06-18 17:01:40 -0700379 bool ret = true;
380 int min_idx = -1;
381 OMX_TICKS min_ts = 0;
382 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700383
Arun Menon906de572013-06-18 17:01:40 -0700384 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700385
Arun Menon906de572013-06-18 17:01:40 -0700386 if (m_ts_arr_list[idx].valid) {
387 //found valid entry, save index
388 if (min_idx < 0) {
389 //first valid entry
390 min_ts = m_ts_arr_list[idx].timestamp;
391 min_idx = idx;
392 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
393 min_ts = m_ts_arr_list[idx].timestamp;
394 min_idx = idx;
395 }
396 }
397
Shalaj Jain273b3e02012-06-22 19:08:03 -0700398 }
399
Arun Menon906de572013-06-18 17:01:40 -0700400 if (min_idx < 0) {
401 //no valid entries found
402 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
403 ts = 0;
404 ret = false;
405 } else {
406 ts = m_ts_arr_list[min_idx].timestamp;
407 m_ts_arr_list[min_idx].valid = false;
408 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
409 ts, min_idx);
410 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700411
Arun Menon906de572013-06-18 17:01:40 -0700412 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700413
414}
415
416
417bool omx_vdec::ts_arr_list::reset_ts_list()
418{
Arun Menon906de572013-06-18 17:01:40 -0700419 bool ret = true;
420 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700421
Arun Menon906de572013-06-18 17:01:40 -0700422 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
423 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
424 m_ts_arr_list[idx].valid = false;
425 }
426 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700427}
428#endif
429
430// factory function executed by the core to create instances
431void *get_omx_component_factory_fn(void)
432{
Arun Menon906de572013-06-18 17:01:40 -0700433 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700434}
435
436#ifdef _ANDROID_
437#ifdef USE_ION
438VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700439 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700440{
Arun Menon906de572013-06-18 17:01:40 -0700441 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700442}
443#else
444VideoHeap::VideoHeap(int fd, size_t size, void* base)
445{
446 // dup file descriptor, map once, use pmem
447 init(dup(fd), base, size, 0 , MEM_DEVICE);
448}
449#endif
450#endif // _ANDROID_
451/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700452 FUNCTION
453 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700454
Arun Menon906de572013-06-18 17:01:40 -0700455 DESCRIPTION
456 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700457
Arun Menon906de572013-06-18 17:01:40 -0700458 PARAMETERS
459 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700460
Arun Menon906de572013-06-18 17:01:40 -0700461 RETURN VALUE
462 None.
463 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800464omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700465 m_state(OMX_StateInvalid),
466 m_app_data(NULL),
467 m_inp_mem_ptr(NULL),
468 m_out_mem_ptr(NULL),
469 m_inp_err_count(0),
470 input_flush_progress (false),
471 output_flush_progress (false),
472 input_use_buffer (false),
473 output_use_buffer (false),
474 ouput_egl_buffers(false),
475 m_use_output_pmem(OMX_FALSE),
476 m_out_mem_region_smi(OMX_FALSE),
477 m_out_pvt_entry_pmem(OMX_FALSE),
478 pending_input_buffers(0),
479 pending_output_buffers(0),
480 m_out_bm_count(0),
481 m_inp_bm_count(0),
482 m_inp_bPopulated(OMX_FALSE),
483 m_out_bPopulated(OMX_FALSE),
484 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700485#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700486 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700487#endif
Arun Menon906de572013-06-18 17:01:40 -0700488 m_inp_bEnabled(OMX_TRUE),
489 m_out_bEnabled(OMX_TRUE),
490 m_in_alloc_cnt(0),
491 m_platform_list(NULL),
492 m_platform_entry(NULL),
493 m_pmem_info(NULL),
494 arbitrary_bytes (true),
495 psource_frame (NULL),
496 pdest_frame (NULL),
497 m_inp_heap_ptr (NULL),
498 m_phdr_pmem_ptr(NULL),
499 m_heap_inp_bm_count (0),
500 codec_type_parse ((codec_type)0),
501 first_frame_meta (true),
502 frame_count (0),
503 nal_count (0),
504 nal_length(0),
505 look_ahead_nal (false),
506 first_frame(0),
507 first_buffer(NULL),
508 first_frame_size (0),
509 m_device_file_ptr(NULL),
510 m_vc1_profile((vc1_profile_type)0),
511 m_profile(0),
512 h264_last_au_ts(LLONG_MAX),
513 h264_last_au_flags(0),
514 prev_ts(LLONG_MAX),
515 rst_prev_ts(true),
516 frm_int(0),
517 m_disp_hor_size(0),
518 m_disp_vert_size(0),
519 in_reconfig(false),
520 m_display_id(NULL),
521 h264_parser(NULL),
522 client_extradata(0),
523 m_reject_avc_1080p_mp (0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700524#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700525 m_enable_android_native_buffers(OMX_FALSE),
526 m_use_android_native_buffers(OMX_FALSE),
527 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700528#endif
Arun Menon906de572013-06-18 17:01:40 -0700529 m_desc_buffer_ptr(NULL),
530 secure_mode(false),
531 client_set_fps(false)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700532{
Arun Menon906de572013-06-18 17:01:40 -0700533 /* Assumption is that , to begin with , we have all the frames with decoder */
534 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700535#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700536 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700537 property_get("vidc.debug.level", property_value, "0");
538 debug_level = atoi(property_value);
539 property_value[0] = '\0';
540
Arun Menon906de572013-06-18 17:01:40 -0700541 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);
Surajit Podder12aefac2013-08-06 18:43:32 +0530721 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
722 bufreq.memory = V4L2_MEMORY_USERPTR;
723 bufreq.count = 0;
724 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
725 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700726 }
727 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700728}
729
Shalaj Jain273b3e02012-06-22 19:08:03 -0700730/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700731 FUNCTION
732 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700733
Arun Menon906de572013-06-18 17:01:40 -0700734 DESCRIPTION
735 IL Client callbacks are generated through this routine. The decoder
736 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700737
Arun Menon906de572013-06-18 17:01:40 -0700738 PARAMETERS
739 ctxt -- Context information related to the self.
740 id -- Event identifier. This could be any of the following:
741 1. Command completion event
742 2. Buffer done callback event
743 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700744
Arun Menon906de572013-06-18 17:01:40 -0700745 RETURN VALUE
746 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700747
Arun Menon906de572013-06-18 17:01:40 -0700748 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700749void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
750{
Arun Menon906de572013-06-18 17:01:40 -0700751 signed p1; // Parameter - 1
752 signed p2; // Parameter - 2
753 unsigned ident;
754 unsigned qsize=0; // qsize
755 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700756
Arun Menon906de572013-06-18 17:01:40 -0700757 if (!pThis) {
758 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
759 __func__);
760 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700761 }
762
Arun Menon906de572013-06-18 17:01:40 -0700763 // Protect the shared queue data structure
764 do {
765 /*Read the message id's from the queue*/
766 pthread_mutex_lock(&pThis->m_lock);
767 qsize = pThis->m_cmd_q.m_size;
768 if (qsize) {
769 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700770 }
Arun Menon906de572013-06-18 17:01:40 -0700771
772 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
773 qsize = pThis->m_ftb_q.m_size;
774 if (qsize) {
775 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
776 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700777 }
Arun Menon906de572013-06-18 17:01:40 -0700778
779 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
780 qsize = pThis->m_etb_q.m_size;
781 if (qsize) {
782 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
783 }
784 }
785 pthread_mutex_unlock(&pThis->m_lock);
786
787 /*process message if we have one*/
788 if (qsize > 0) {
789 id = ident;
790 switch (id) {
791 case OMX_COMPONENT_GENERATE_EVENT:
792 if (pThis->m_cb.EventHandler) {
793 switch (p1) {
794 case OMX_CommandStateSet:
795 pThis->m_state = (OMX_STATETYPE) p2;
796 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
797 pThis->m_state);
798 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
799 OMX_EventCmdComplete, p1, p2, NULL);
800 break;
801
802 case OMX_EventError:
803 if (p2 == OMX_StateInvalid) {
804 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
805 pThis->m_state = (OMX_STATETYPE) p2;
806 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
807 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
808 } else if (p2 == OMX_ErrorHardware) {
809 pThis->omx_report_error();
810 } else {
811 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
812 OMX_EventError, p2, (OMX_U32)NULL, NULL );
813 }
814 break;
815
816 case OMX_CommandPortDisable:
817 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
818 if (BITMASK_PRESENT(&pThis->m_flags,
819 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
820 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
821 break;
822 }
823 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
824 OMX_ERRORTYPE eRet = OMX_ErrorNone;
825 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
826 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
827 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
828 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
829 pThis->in_reconfig = false;
830 if (eRet != OMX_ErrorNone) {
831 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
832 pThis->omx_report_error();
833 break;
834 }
835 }
836 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
837 OMX_EventCmdComplete, p1, p2, NULL );
838 break;
839 case OMX_CommandPortEnable:
840 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
841 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
842 OMX_EventCmdComplete, p1, p2, NULL );
843 break;
844
845 default:
846 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
847 OMX_EventCmdComplete, p1, p2, NULL );
848 break;
849
850 }
851 } else {
852 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
853 }
854 break;
855 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
856 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
857 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
858 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
859 pThis->omx_report_error ();
860 }
861 break;
862 case OMX_COMPONENT_GENERATE_ETB:
863 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
864 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
865 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
866 pThis->omx_report_error ();
867 }
868 break;
869
870 case OMX_COMPONENT_GENERATE_FTB:
871 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
872 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
873 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
874 pThis->omx_report_error ();
875 }
876 break;
877
878 case OMX_COMPONENT_GENERATE_COMMAND:
879 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
880 (OMX_U32)p2,(OMX_PTR)NULL);
881 break;
882
883 case OMX_COMPONENT_GENERATE_EBD:
884
885 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
886 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
887 pThis->omx_report_error ();
888 } else {
889 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
890 pThis->m_inp_err_count++;
891 pThis->time_stamp_dts.remove_time_stamp(
892 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
893 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
894 ?true:false);
895 } else {
896 pThis->m_inp_err_count = 0;
897 }
898 if ( pThis->empty_buffer_done(&pThis->m_cmp,
899 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
900 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
901 pThis->omx_report_error ();
902 }
903 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
904 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
905 pThis->omx_report_error ();
906 }
907 }
908 break;
909 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
910 int64_t *timestamp = (int64_t *)p1;
911 if (p1) {
912 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
913 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
914 ?true:false);
915 free(timestamp);
916 }
917 }
918 break;
919 case OMX_COMPONENT_GENERATE_FBD:
920 if (p2 != VDEC_S_SUCCESS) {
921 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
922 pThis->omx_report_error ();
923 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
924 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
925 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
926 pThis->omx_report_error ();
927 }
928 break;
929
930 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
931 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
932 if (!pThis->input_flush_progress) {
933 DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
934 } else {
935 pThis->execute_input_flush();
936 if (pThis->m_cb.EventHandler) {
937 if (p2 != VDEC_S_SUCCESS) {
938 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
939 pThis->omx_report_error ();
940 } else {
941 /*Check if we need generate event for Flush done*/
942 if (BITMASK_PRESENT(&pThis->m_flags,
943 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
944 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
945 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
946 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
947 OMX_EventCmdComplete,OMX_CommandFlush,
948 OMX_CORE_INPUT_PORT_INDEX,NULL );
949 }
950 if (BITMASK_PRESENT(&pThis->m_flags,
951 OMX_COMPONENT_IDLE_PENDING)) {
952 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
953 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
954 pThis->omx_report_error ();
955 } else {
956 pThis->streaming[OUTPUT_PORT] = false;
957 }
958 if (!pThis->output_flush_progress) {
959 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
960 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
961 OMX_COMPONENT_GENERATE_STOP_DONE);
962 }
963 }
964 }
965 } else {
966 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
967 }
968 }
969 break;
970
971 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
972 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
973 if (!pThis->output_flush_progress) {
974 DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
975 } else {
976 pThis->execute_output_flush();
977 if (pThis->m_cb.EventHandler) {
978 if (p2 != VDEC_S_SUCCESS) {
979 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
980 pThis->omx_report_error ();
981 } else {
982 /*Check if we need generate event for Flush done*/
983 if (BITMASK_PRESENT(&pThis->m_flags,
984 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
985 DEBUG_PRINT_LOW("\n Notify Output Flush done");
986 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
987 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
988 OMX_EventCmdComplete,OMX_CommandFlush,
989 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
990 }
991 if (BITMASK_PRESENT(&pThis->m_flags,
992 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
993 DEBUG_PRINT_LOW("\n Internal flush complete");
994 BITMASK_CLEAR (&pThis->m_flags,
995 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
996 if (BITMASK_PRESENT(&pThis->m_flags,
997 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
998 pThis->post_event(OMX_CommandPortDisable,
999 OMX_CORE_OUTPUT_PORT_INDEX,
1000 OMX_COMPONENT_GENERATE_EVENT);
1001 BITMASK_CLEAR (&pThis->m_flags,
1002 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1003
1004 }
1005 }
1006
1007 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1008 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
1009 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1010 pThis->omx_report_error ();
1011 break;
1012 }
1013 pThis->streaming[CAPTURE_PORT] = false;
1014 if (!pThis->input_flush_progress) {
1015 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
1016 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1017 OMX_COMPONENT_GENERATE_STOP_DONE);
1018 }
1019 }
1020 }
1021 } else {
1022 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1023 }
1024 }
1025 break;
1026
1027 case OMX_COMPONENT_GENERATE_START_DONE:
1028 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1029
1030 if (pThis->m_cb.EventHandler) {
1031 if (p2 != VDEC_S_SUCCESS) {
1032 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1033 pThis->omx_report_error ();
1034 } else {
1035 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1036 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1037 DEBUG_PRINT_LOW("\n Move to executing");
1038 // Send the callback now
1039 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1040 pThis->m_state = OMX_StateExecuting;
1041 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1042 OMX_EventCmdComplete,OMX_CommandStateSet,
1043 OMX_StateExecuting, NULL);
1044 } else if (BITMASK_PRESENT(&pThis->m_flags,
1045 OMX_COMPONENT_PAUSE_PENDING)) {
1046 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1047 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
1048 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1049 pThis->omx_report_error ();
1050 }
1051 }
1052 }
1053 } else {
1054 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1055 }
1056 break;
1057
1058 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1059 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1060 if (pThis->m_cb.EventHandler) {
1061 if (p2 != VDEC_S_SUCCESS) {
1062 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1063 pThis->omx_report_error ();
1064 } else {
1065 pThis->complete_pending_buffer_done_cbs();
1066 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
1067 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1068 //Send the callback now
1069 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1070 pThis->m_state = OMX_StatePause;
1071 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1072 OMX_EventCmdComplete,OMX_CommandStateSet,
1073 OMX_StatePause, NULL);
1074 }
1075 }
1076 } else {
1077 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1078 }
1079
1080 break;
1081
1082 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1083 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1084 if (pThis->m_cb.EventHandler) {
1085 if (p2 != VDEC_S_SUCCESS) {
1086 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1087 pThis->omx_report_error ();
1088 } else {
1089 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1090 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1091 // Send the callback now
1092 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1093 pThis->m_state = OMX_StateExecuting;
1094 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1095 OMX_EventCmdComplete,OMX_CommandStateSet,
1096 OMX_StateExecuting,NULL);
1097 }
1098 }
1099 } else {
1100 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1101 }
1102
1103 break;
1104
1105 case OMX_COMPONENT_GENERATE_STOP_DONE:
1106 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1107 if (pThis->m_cb.EventHandler) {
1108 if (p2 != VDEC_S_SUCCESS) {
1109 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1110 pThis->omx_report_error ();
1111 } else {
1112 pThis->complete_pending_buffer_done_cbs();
1113 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
1114 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1115 // Send the callback now
1116 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1117 pThis->m_state = OMX_StateIdle;
1118 DEBUG_PRINT_LOW("\n Move to Idle State");
1119 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1120 OMX_EventCmdComplete,OMX_CommandStateSet,
1121 OMX_StateIdle,NULL);
1122 }
1123 }
1124 } else {
1125 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1126 }
1127
1128 break;
1129
1130 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1131 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
1132
1133 if (p2 == OMX_IndexParamPortDefinition) {
1134 pThis->in_reconfig = true;
1135 }
1136 if (pThis->m_cb.EventHandler) {
1137 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1138 OMX_EventPortSettingsChanged, p1, p2, NULL );
1139 } else {
1140 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1141 }
1142
Arun Menon906de572013-06-18 17:01:40 -07001143 break;
1144
1145 case OMX_COMPONENT_GENERATE_EOS_DONE:
1146 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1147 if (pThis->m_cb.EventHandler) {
1148 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1149 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1150 } else {
1151 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1152 }
1153 pThis->prev_ts = LLONG_MAX;
1154 pThis->rst_prev_ts = true;
1155 break;
1156
1157 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1158 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1159 pThis->omx_report_error ();
1160 break;
1161
1162 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1163 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
1164 pThis->omx_report_unsupported_setting();
1165 break;
1166
Arun Menon906de572013-06-18 17:01:40 -07001167 default:
1168 break;
1169 }
1170 }
1171 pthread_mutex_lock(&pThis->m_lock);
1172 qsize = pThis->m_cmd_q.m_size;
1173 if (pThis->m_state != OMX_StatePause)
1174 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1175 pthread_mutex_unlock(&pThis->m_lock);
1176 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001177
1178}
1179
Vinay Kaliab9e98102013-04-02 19:31:43 -07001180int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001181{
Arun Menon906de572013-06-18 17:01:40 -07001182 int format_changed = 0;
1183 if ((height != drv_ctx.video_resolution.frame_height) ||
1184 (width != drv_ctx.video_resolution.frame_width)) {
1185 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)\n",
1186 width, drv_ctx.video_resolution.frame_width,
1187 height,drv_ctx.video_resolution.frame_height);
1188 format_changed = 1;
1189 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001190 drv_ctx.video_resolution.frame_height = height;
1191 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001192 drv_ctx.video_resolution.scan_lines = scan_lines;
1193 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001194 rectangle.nLeft = 0;
1195 rectangle.nTop = 0;
1196 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1197 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Arun Menon906de572013-06-18 17:01:40 -07001198 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001199}
1200
Arun Menon6836ba02013-02-19 20:37:40 -08001201OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1202{
Arun Menon906de572013-06-18 17:01:40 -07001203 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1204 OMX_MAX_STRINGNAME_SIZE) &&
1205 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1206 m_decoder_capability.max_width = 1280;
1207 m_decoder_capability.max_height = 720;
1208 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1209 }
Arun Menon888aa852013-05-30 11:24:42 -07001210
Arun Menon906de572013-06-18 17:01:40 -07001211 if ((drv_ctx.video_resolution.frame_width *
1212 drv_ctx.video_resolution.frame_height >
1213 m_decoder_capability.max_width *
1214 m_decoder_capability.max_height) ||
1215 (drv_ctx.video_resolution.frame_width*
1216 drv_ctx.video_resolution.frame_height <
1217 m_decoder_capability.min_width *
1218 m_decoder_capability.min_height)) {
1219 DEBUG_PRINT_ERROR(
1220 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1221 drv_ctx.video_resolution.frame_width,
1222 drv_ctx.video_resolution.frame_height,
1223 m_decoder_capability.min_width,
1224 m_decoder_capability.min_height,
1225 m_decoder_capability.max_width,
1226 m_decoder_capability.max_height);
1227 return OMX_ErrorUnsupportedSetting;
1228 }
1229 DEBUG_PRINT_HIGH("\n video session supported\n");
1230 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001231}
1232
Shalaj Jain273b3e02012-06-22 19:08:03 -07001233/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001234 FUNCTION
1235 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001236
Arun Menon906de572013-06-18 17:01:40 -07001237 DESCRIPTION
1238 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001239
Arun Menon906de572013-06-18 17:01:40 -07001240 PARAMETERS
1241 ctxt -- Context information related to the self.
1242 id -- Event identifier. This could be any of the following:
1243 1. Command completion event
1244 2. Buffer done callback event
1245 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001246
Arun Menon906de572013-06-18 17:01:40 -07001247 RETURN VALUE
1248 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001249
Arun Menon906de572013-06-18 17:01:40 -07001250 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001251OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1252{
1253
Arun Menon906de572013-06-18 17:01:40 -07001254 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1255 struct v4l2_fmtdesc fdesc;
1256 struct v4l2_format fmt;
1257 struct v4l2_requestbuffers bufreq;
1258 struct v4l2_control control;
1259 struct v4l2_frmsizeenum frmsize;
1260 unsigned int alignment = 0,buffer_size = 0;
1261 int fds[2];
1262 int r,ret=0;
1263 bool codec_ambiguous = false;
1264 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Sachin Shahc82a18f2013-03-29 14:45:38 -07001265
1266#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07001267 char platform_name[64];
1268 property_get("ro.board.platform", platform_name, "0");
1269 if (!strncmp(platform_name, "msm8610", 7)) {
1270 device_name = (OMX_STRING)"/dev/video/q6_dec";
1271 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001272#endif
1273
Arun Menon906de572013-06-18 17:01:40 -07001274 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1275 struct v4l2_control control;
1276 secure_mode = true;
1277 arbitrary_bytes = false;
1278 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
1279 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001280
Arun Menon906de572013-06-18 17:01:40 -07001281 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001282
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001283 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d",
1284 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001285
Arun Menon906de572013-06-18 17:01:40 -07001286 if (drv_ctx.video_driver_fd == 0) {
1287 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again\n");
1288 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1289 close(0);
1290 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001291
Arun Menon906de572013-06-18 17:01:40 -07001292 if (drv_ctx.video_driver_fd < 0) {
1293 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1294 return OMX_ErrorInsufficientResources;
1295 }
1296 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1297 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001298
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001299 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001300 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001301 async_thread_created = true;
1302 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1303 }
1304 if (ret) {
1305 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1306 async_thread_created = false;
1307 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001308 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001309
1310#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001311 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001312#endif
1313#ifdef OUTPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001314 outputBufferFile1 = fopen (outputfilename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001315#endif
1316#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07001317 outputExtradataFile = fopen (ouputextradatafilename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001318#endif
1319
Arun Menon906de572013-06-18 17:01:40 -07001320 // Copy the role information which provides the decoder kind
1321 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001322
Arun Menon906de572013-06-18 17:01:40 -07001323 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1324 OMX_MAX_STRINGNAME_SIZE)) {
1325 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1326 OMX_MAX_STRINGNAME_SIZE);
1327 drv_ctx.timestamp_adjust = true;
1328 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1329 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1330 output_capability=V4L2_PIX_FMT_MPEG4;
1331 /*Initialize Start Code for MPEG4*/
1332 codec_type_parse = CODEC_TYPE_MPEG4;
1333 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001334#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001335 strcat(inputfilename, "m4v");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001336#endif
Arun Menon906de572013-06-18 17:01:40 -07001337 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1338 OMX_MAX_STRINGNAME_SIZE)) {
1339 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1340 OMX_MAX_STRINGNAME_SIZE);
1341 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1342 output_capability = V4L2_PIX_FMT_MPEG2;
1343 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1344 /*Initialize Start Code for MPEG2*/
1345 codec_type_parse = CODEC_TYPE_MPEG2;
1346 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001347#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001348 strcat(inputfilename, "mpg");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001349#endif
Arun Menon906de572013-06-18 17:01:40 -07001350 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1351 OMX_MAX_STRINGNAME_SIZE)) {
1352 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1353 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1354 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1355 eCompressionFormat = OMX_VIDEO_CodingH263;
1356 output_capability = V4L2_PIX_FMT_H263;
1357 codec_type_parse = CODEC_TYPE_H263;
1358 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001359#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001360 strcat(inputfilename, "263");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001361#endif
Arun Menon906de572013-06-18 17:01:40 -07001362 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1363 OMX_MAX_STRINGNAME_SIZE)) {
1364 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1365 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1366 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1367 output_capability = V4L2_PIX_FMT_DIVX_311;
1368 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1369 codec_type_parse = CODEC_TYPE_DIVX;
1370 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001371
Arun Menon906de572013-06-18 17:01:40 -07001372 eRet = createDivxDrmContext();
1373 if (eRet != OMX_ErrorNone) {
1374 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1375 return eRet;
1376 }
1377 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1378 OMX_MAX_STRINGNAME_SIZE)) {
1379 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1380 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1381 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1382 output_capability = V4L2_PIX_FMT_DIVX;
1383 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1384 codec_type_parse = CODEC_TYPE_DIVX;
1385 codec_ambiguous = true;
1386 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001387
Arun Menon906de572013-06-18 17:01:40 -07001388 eRet = createDivxDrmContext();
1389 if (eRet != OMX_ErrorNone) {
1390 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1391 return eRet;
1392 }
1393 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1394 OMX_MAX_STRINGNAME_SIZE)) {
1395 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1396 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1397 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1398 output_capability = V4L2_PIX_FMT_DIVX;
1399 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1400 codec_type_parse = CODEC_TYPE_DIVX;
1401 codec_ambiguous = true;
1402 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001403
Arun Menon906de572013-06-18 17:01:40 -07001404 eRet = createDivxDrmContext();
1405 if (eRet != OMX_ErrorNone) {
1406 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1407 return eRet;
1408 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001409
Arun Menon906de572013-06-18 17:01:40 -07001410 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1411 OMX_MAX_STRINGNAME_SIZE)) {
1412 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1413 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1414 output_capability=V4L2_PIX_FMT_H264;
1415 eCompressionFormat = OMX_VIDEO_CodingAVC;
1416 codec_type_parse = CODEC_TYPE_H264;
1417 m_frame_parser.init_start_codes (codec_type_parse);
1418 m_frame_parser.init_nal_length(nal_length);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001419#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001420 strcat(inputfilename, "264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001421#endif
Arun Menon906de572013-06-18 17:01:40 -07001422 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1423 OMX_MAX_STRINGNAME_SIZE)) {
1424 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1425 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1426 eCompressionFormat = OMX_VIDEO_CodingWMV;
1427 codec_type_parse = CODEC_TYPE_VC1;
1428 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1429 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001430#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001431 strcat(inputfilename, "vc1");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001432#endif
Arun Menon906de572013-06-18 17:01:40 -07001433 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1434 OMX_MAX_STRINGNAME_SIZE)) {
1435 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1436 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1437 eCompressionFormat = OMX_VIDEO_CodingWMV;
1438 codec_type_parse = CODEC_TYPE_VC1;
1439 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1440 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001441#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001442 strcat(inputfilename, "vc1");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001443#endif
Arun Menon906de572013-06-18 17:01:40 -07001444 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1445 OMX_MAX_STRINGNAME_SIZE)) {
1446 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1447 output_capability=V4L2_PIX_FMT_VP8;
1448 eCompressionFormat = OMX_VIDEO_CodingVPX;
1449 codec_type_parse = CODEC_TYPE_VP8;
1450 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001451#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001452 strcat(inputfilename, "ivf");
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001453#endif
1454
Arun Menon906de572013-06-18 17:01:40 -07001455 } else {
1456 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1457 eRet = OMX_ErrorInvalidComponentName;
1458 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001459#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07001460 inputBufferFile1 = fopen (inputfilename, "ab");
1461 if (output_capability == V4L2_PIX_FMT_VP8) {
1462 struct ivf_file_header {
1463 OMX_U8 signature[4]; //='DKIF';
1464 OMX_U8 version ; //= 0;
1465 OMX_U8 headersize ; //= 32;
1466 OMX_U32 FourCC;
1467 OMX_U8 width;
1468 OMX_U8 height;
1469 OMX_U32 rate;
1470 OMX_U32 scale;
1471 OMX_U32 length;
1472 OMX_U8 unused[4];
1473 } file_header;
1474 memset((void *)&file_header,0,sizeof(file_header));
1475 file_header.signature[0] = 'D';
1476 file_header.signature[1] = 'K';
1477 file_header.signature[2] = 'I';
1478 file_header.signature[3] = 'F';
1479 file_header.version = 0;
1480 file_header.headersize = 32;
1481 file_header.FourCC = 0x30385056;
1482 if (inputBufferFile1) {
1483 fwrite((const char *)&file_header,
1484 sizeof(file_header),1,inputBufferFile1);
1485 }
1486 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001487#endif
Arun Menon906de572013-06-18 17:01:40 -07001488 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001489
Arun Menon906de572013-06-18 17:01:40 -07001490 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001491 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1492 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1493 if (!client_buffers.set_color_format(dest_color_format)) {
1494 DEBUG_PRINT_ERROR("\n Setting color format failed");
1495 eRet = OMX_ErrorInsufficientResources;
1496 }
1497
Arun Menon906de572013-06-18 17:01:40 -07001498 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001499
Arun Menon906de572013-06-18 17:01:40 -07001500 struct v4l2_capability cap;
1501 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1502 if (ret) {
1503 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
1504 /*TODO: How to handle this case */
1505 } else {
1506 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
1507 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1508 cap.bus_info, cap.version, cap.capabilities);
1509 }
1510 ret=0;
1511 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1512 fdesc.index=0;
1513 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1514 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
1515 fdesc.pixelformat, fdesc.flags);
1516 fdesc.index++;
1517 }
1518 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1519 fdesc.index=0;
1520 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001521
Arun Menon906de572013-06-18 17:01:40 -07001522 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
1523 fdesc.pixelformat, fdesc.flags);
1524 fdesc.index++;
1525 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001526 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001527 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1528 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1529 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1530 fmt.fmt.pix_mp.pixelformat = output_capability;
1531 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1532 if (ret) {
1533 /*TODO: How to handle this case */
1534 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
1535 return OMX_ErrorInsufficientResources;
1536 }
1537 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
1538 if (codec_ambiguous) {
1539 if (output_capability == V4L2_PIX_FMT_DIVX) {
1540 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001541
Arun Menon906de572013-06-18 17:01:40 -07001542 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1543 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1544 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1545 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1546 } else {
1547 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1548 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001549
Arun Menon906de572013-06-18 17:01:40 -07001550 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1551 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1552 if (ret) {
1553 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1554 }
1555 } else {
1556 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1557 }
1558 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001559
Arun Menon906de572013-06-18 17:01:40 -07001560 //Get the hardware capabilities
1561 memset((void *)&frmsize,0,sizeof(frmsize));
1562 frmsize.index = 0;
1563 frmsize.pixel_format = output_capability;
1564 ret = ioctl(drv_ctx.video_driver_fd,
1565 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1566 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1567 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1568 return OMX_ErrorHardware;
1569 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001570
Arun Menon906de572013-06-18 17:01:40 -07001571 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1572 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1573 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1574 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1575 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1576 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001577
Arun Menon906de572013-06-18 17:01:40 -07001578 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1579 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1580 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1581 fmt.fmt.pix_mp.pixelformat = capture_capability;
1582 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1583 if (ret) {
1584 /*TODO: How to handle this case */
1585 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
1586 }
1587 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
1588 if (secure_mode) {
1589 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1590 control.value = 1;
1591 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1592 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1593 if (ret) {
1594 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1595 return OMX_ErrorInsufficientResources;
1596 }
1597 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001598
Arun Menon906de572013-06-18 17:01:40 -07001599 /*Get the Buffer requirements for input and output ports*/
1600 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1601 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1602 if (secure_mode) {
1603 drv_ctx.op_buf.alignment=SZ_1M;
1604 drv_ctx.ip_buf.alignment=SZ_1M;
1605 } else {
1606 drv_ctx.op_buf.alignment=SZ_4K;
1607 drv_ctx.ip_buf.alignment=SZ_4K;
1608 }
1609 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1610 drv_ctx.extradata = 0;
1611 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1612 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1613 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1614 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1615 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001616
Vinay Kalia5713bb32013-01-16 18:39:59 -08001617 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001618#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001619 if (eRet == OMX_ErrorNone && !secure_mode)
1620 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001621#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001622 eRet=get_buffer_req(&drv_ctx.ip_buf);
1623 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1624 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001625 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1626 if (m_frame_parser.mutils == NULL) {
1627 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001628
Arun Menon906de572013-06-18 17:01:40 -07001629 if (m_frame_parser.mutils == NULL) {
1630 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1631 eRet = OMX_ErrorInsufficientResources;
1632 } else {
1633 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1634 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1635 h264_scratch.nFilledLen = 0;
1636 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001637
Arun Menon906de572013-06-18 17:01:40 -07001638 if (h264_scratch.pBuffer == NULL) {
1639 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1640 return OMX_ErrorInsufficientResources;
1641 }
1642 m_frame_parser.mutils->initialize_frame_checking_environment();
1643 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1644 }
1645 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001646
Arun Menon906de572013-06-18 17:01:40 -07001647 h264_parser = new h264_stream_parser();
1648 if (!h264_parser) {
1649 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1650 eRet = OMX_ErrorInsufficientResources;
1651 }
1652 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001653
Arun Menon906de572013-06-18 17:01:40 -07001654 if (pipe(fds)) {
1655 DEBUG_PRINT_ERROR("pipe creation failed\n");
1656 eRet = OMX_ErrorInsufficientResources;
1657 } else {
1658 int temp1[2];
1659 if (fds[0] == 0 || fds[1] == 0) {
1660 if (pipe (temp1)) {
1661 DEBUG_PRINT_ERROR("pipe creation failed\n");
1662 return OMX_ErrorInsufficientResources;
1663 }
1664 //close (fds[0]);
1665 //close (fds[1]);
1666 fds[0] = temp1 [0];
1667 fds[1] = temp1 [1];
1668 }
1669 m_pipe_in = fds[0];
1670 m_pipe_out = fds[1];
1671 msg_thread_created = true;
1672 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001673
Arun Menon906de572013-06-18 17:01:40 -07001674 if (r < 0) {
1675 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1676 msg_thread_created = false;
1677 eRet = OMX_ErrorInsufficientResources;
1678 }
1679 }
1680 }
1681
1682 if (eRet != OMX_ErrorNone) {
1683 DEBUG_PRINT_ERROR("\n Component Init Failed");
1684 } else {
1685 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1686 }
1687 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1688 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001689}
1690
1691/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001692 FUNCTION
1693 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001694
Arun Menon906de572013-06-18 17:01:40 -07001695 DESCRIPTION
1696 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001697
Arun Menon906de572013-06-18 17:01:40 -07001698 PARAMETERS
1699 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001700
Arun Menon906de572013-06-18 17:01:40 -07001701 RETURN VALUE
1702 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001703
Arun Menon906de572013-06-18 17:01:40 -07001704 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001705OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001706(
1707 OMX_IN OMX_HANDLETYPE hComp,
1708 OMX_OUT OMX_STRING componentName,
1709 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1710 OMX_OUT OMX_VERSIONTYPE* specVersion,
1711 OMX_OUT OMX_UUIDTYPE* componentUUID
1712 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001713{
Arun Menon906de572013-06-18 17:01:40 -07001714 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001715 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1716 return OMX_ErrorInvalidState;
1717 }
Arun Menon906de572013-06-18 17:01:40 -07001718 /* TBD -- Return the proper version */
1719 if (specVersion) {
1720 specVersion->nVersion = OMX_SPEC_VERSION;
1721 }
1722 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001723}
1724/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001725 FUNCTION
1726 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001727
Arun Menon906de572013-06-18 17:01:40 -07001728 DESCRIPTION
1729 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001730
Arun Menon906de572013-06-18 17:01:40 -07001731 PARAMETERS
1732 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001733
Arun Menon906de572013-06-18 17:01:40 -07001734 RETURN VALUE
1735 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001736
Arun Menon906de572013-06-18 17:01:40 -07001737 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001738OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001739 OMX_IN OMX_COMMANDTYPE cmd,
1740 OMX_IN OMX_U32 param1,
1741 OMX_IN OMX_PTR cmdData
1742 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001743{
1744 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001745 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001746 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1747 return OMX_ErrorInvalidState;
1748 }
1749 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001750 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
1751 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
1752 "to invalid port: %lu", param1);
1753 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001754 }
1755 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1756 sem_wait(&m_cmd_lock);
1757 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1758 return OMX_ErrorNone;
1759}
1760
1761/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001762 FUNCTION
1763 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001764
Arun Menon906de572013-06-18 17:01:40 -07001765 DESCRIPTION
1766 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001767
Arun Menon906de572013-06-18 17:01:40 -07001768 PARAMETERS
1769 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001770
Arun Menon906de572013-06-18 17:01:40 -07001771 RETURN VALUE
1772 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001773
Arun Menon906de572013-06-18 17:01:40 -07001774 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001775OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001776 OMX_IN OMX_COMMANDTYPE cmd,
1777 OMX_IN OMX_U32 param1,
1778 OMX_IN OMX_PTR cmdData
1779 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001780{
Arun Menon906de572013-06-18 17:01:40 -07001781 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1782 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1783 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001784
Arun Menon906de572013-06-18 17:01:40 -07001785 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1786 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1787 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001788
Arun Menon906de572013-06-18 17:01:40 -07001789 if (cmd == OMX_CommandStateSet) {
1790 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1791 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1792 /***************************/
1793 /* Current State is Loaded */
1794 /***************************/
1795 if (m_state == OMX_StateLoaded) {
1796 if (eState == OMX_StateIdle) {
1797 //if all buffers are allocated or all ports disabled
1798 if (allocate_done() ||
1799 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
1800 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1801 } else {
1802 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1803 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1804 // Skip the event notification
1805 bFlag = 0;
1806 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001807 }
Arun Menon906de572013-06-18 17:01:40 -07001808 /* Requesting transition from Loaded to Loaded */
1809 else if (eState == OMX_StateLoaded) {
1810 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1811 post_event(OMX_EventError,OMX_ErrorSameState,\
1812 OMX_COMPONENT_GENERATE_EVENT);
1813 eRet = OMX_ErrorSameState;
1814 }
1815 /* Requesting transition from Loaded to WaitForResources */
1816 else if (eState == OMX_StateWaitForResources) {
1817 /* Since error is None , we will post an event
1818 at the end of this function definition */
1819 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1820 }
1821 /* Requesting transition from Loaded to Executing */
1822 else if (eState == OMX_StateExecuting) {
1823 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1824 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1825 OMX_COMPONENT_GENERATE_EVENT);
1826 eRet = OMX_ErrorIncorrectStateTransition;
1827 }
1828 /* Requesting transition from Loaded to Pause */
1829 else if (eState == OMX_StatePause) {
1830 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1831 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1832 OMX_COMPONENT_GENERATE_EVENT);
1833 eRet = OMX_ErrorIncorrectStateTransition;
1834 }
1835 /* Requesting transition from Loaded to Invalid */
1836 else if (eState == OMX_StateInvalid) {
1837 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1838 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1839 eRet = OMX_ErrorInvalidState;
1840 } else {
1841 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1842 eState);
1843 eRet = OMX_ErrorBadParameter;
1844 }
1845 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001846
Arun Menon906de572013-06-18 17:01:40 -07001847 /***************************/
1848 /* Current State is IDLE */
1849 /***************************/
1850 else if (m_state == OMX_StateIdle) {
1851 if (eState == OMX_StateLoaded) {
1852 if (release_done()) {
1853 /*
1854 Since error is None , we will post an event at the end
1855 of this function definition
1856 */
1857 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
1858 } else {
1859 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
1860 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1861 // Skip the event notification
1862 bFlag = 0;
1863 }
1864 }
1865 /* Requesting transition from Idle to Executing */
1866 else if (eState == OMX_StateExecuting) {
1867 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1868 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1869 bFlag = 1;
1870 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1871 m_state=OMX_StateExecuting;
1872 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
1873 }
1874 /* Requesting transition from Idle to Idle */
1875 else if (eState == OMX_StateIdle) {
1876 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
1877 post_event(OMX_EventError,OMX_ErrorSameState,\
1878 OMX_COMPONENT_GENERATE_EVENT);
1879 eRet = OMX_ErrorSameState;
1880 }
1881 /* Requesting transition from Idle to WaitForResources */
1882 else if (eState == OMX_StateWaitForResources) {
1883 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
1884 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1885 OMX_COMPONENT_GENERATE_EVENT);
1886 eRet = OMX_ErrorIncorrectStateTransition;
1887 }
1888 /* Requesting transition from Idle to Pause */
1889 else if (eState == OMX_StatePause) {
1890 /*To pause the Video core we need to start the driver*/
1891 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
1892 NULL) < */0) {
1893 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
1894 omx_report_error ();
1895 eRet = OMX_ErrorHardware;
1896 } else {
1897 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1898 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
1899 bFlag = 0;
1900 }
1901 }
1902 /* Requesting transition from Idle to Invalid */
1903 else if (eState == OMX_StateInvalid) {
1904 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
1905 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1906 eRet = OMX_ErrorInvalidState;
1907 } else {
1908 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
1909 eRet = OMX_ErrorBadParameter;
1910 }
1911 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001912
Arun Menon906de572013-06-18 17:01:40 -07001913 /******************************/
1914 /* Current State is Executing */
1915 /******************************/
1916 else if (m_state == OMX_StateExecuting) {
1917 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
1918 /* Requesting transition from Executing to Idle */
1919 if (eState == OMX_StateIdle) {
1920 /* Since error is None , we will post an event
1921 at the end of this function definition
1922 */
1923 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
1924 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1925 if (!sem_posted) {
1926 sem_posted = 1;
1927 sem_post (&m_cmd_lock);
1928 execute_omx_flush(OMX_ALL);
1929 }
1930 bFlag = 0;
1931 }
1932 /* Requesting transition from Executing to Paused */
1933 else if (eState == OMX_StatePause) {
1934 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
1935 m_state = OMX_StatePause;
1936 bFlag = 1;
1937 }
1938 /* Requesting transition from Executing to Loaded */
1939 else if (eState == OMX_StateLoaded) {
1940 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
1941 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1942 OMX_COMPONENT_GENERATE_EVENT);
1943 eRet = OMX_ErrorIncorrectStateTransition;
1944 }
1945 /* Requesting transition from Executing to WaitForResources */
1946 else if (eState == OMX_StateWaitForResources) {
1947 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
1948 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1949 OMX_COMPONENT_GENERATE_EVENT);
1950 eRet = OMX_ErrorIncorrectStateTransition;
1951 }
1952 /* Requesting transition from Executing to Executing */
1953 else if (eState == OMX_StateExecuting) {
1954 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
1955 post_event(OMX_EventError,OMX_ErrorSameState,\
1956 OMX_COMPONENT_GENERATE_EVENT);
1957 eRet = OMX_ErrorSameState;
1958 }
1959 /* Requesting transition from Executing to Invalid */
1960 else if (eState == OMX_StateInvalid) {
1961 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
1962 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1963 eRet = OMX_ErrorInvalidState;
1964 } else {
1965 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
1966 eRet = OMX_ErrorBadParameter;
1967 }
1968 }
1969 /***************************/
1970 /* Current State is Pause */
1971 /***************************/
1972 else if (m_state == OMX_StatePause) {
1973 /* Requesting transition from Pause to Executing */
1974 if (eState == OMX_StateExecuting) {
1975 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
1976 m_state = OMX_StateExecuting;
1977 bFlag = 1;
1978 }
1979 /* Requesting transition from Pause to Idle */
1980 else if (eState == OMX_StateIdle) {
1981 /* Since error is None , we will post an event
1982 at the end of this function definition */
1983 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
1984 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1985 if (!sem_posted) {
1986 sem_posted = 1;
1987 sem_post (&m_cmd_lock);
1988 execute_omx_flush(OMX_ALL);
1989 }
1990 bFlag = 0;
1991 }
1992 /* Requesting transition from Pause to loaded */
1993 else if (eState == OMX_StateLoaded) {
1994 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
1995 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1996 OMX_COMPONENT_GENERATE_EVENT);
1997 eRet = OMX_ErrorIncorrectStateTransition;
1998 }
1999 /* Requesting transition from Pause to WaitForResources */
2000 else if (eState == OMX_StateWaitForResources) {
2001 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2002 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2003 OMX_COMPONENT_GENERATE_EVENT);
2004 eRet = OMX_ErrorIncorrectStateTransition;
2005 }
2006 /* Requesting transition from Pause to Pause */
2007 else if (eState == OMX_StatePause) {
2008 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2009 post_event(OMX_EventError,OMX_ErrorSameState,\
2010 OMX_COMPONENT_GENERATE_EVENT);
2011 eRet = OMX_ErrorSameState;
2012 }
2013 /* Requesting transition from Pause to Invalid */
2014 else if (eState == OMX_StateInvalid) {
2015 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2016 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2017 eRet = OMX_ErrorInvalidState;
2018 } else {
2019 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2020 eRet = OMX_ErrorBadParameter;
2021 }
2022 }
2023 /***************************/
2024 /* Current State is WaitForResources */
2025 /***************************/
2026 else if (m_state == OMX_StateWaitForResources) {
2027 /* Requesting transition from WaitForResources to Loaded */
2028 if (eState == OMX_StateLoaded) {
2029 /* Since error is None , we will post an event
2030 at the end of this function definition */
2031 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2032 }
2033 /* Requesting transition from WaitForResources to WaitForResources */
2034 else if (eState == OMX_StateWaitForResources) {
2035 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2036 post_event(OMX_EventError,OMX_ErrorSameState,
2037 OMX_COMPONENT_GENERATE_EVENT);
2038 eRet = OMX_ErrorSameState;
2039 }
2040 /* Requesting transition from WaitForResources to Executing */
2041 else if (eState == OMX_StateExecuting) {
2042 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2043 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2044 OMX_COMPONENT_GENERATE_EVENT);
2045 eRet = OMX_ErrorIncorrectStateTransition;
2046 }
2047 /* Requesting transition from WaitForResources to Pause */
2048 else if (eState == OMX_StatePause) {
2049 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2050 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2051 OMX_COMPONENT_GENERATE_EVENT);
2052 eRet = OMX_ErrorIncorrectStateTransition;
2053 }
2054 /* Requesting transition from WaitForResources to Invalid */
2055 else if (eState == OMX_StateInvalid) {
2056 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2057 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2058 eRet = OMX_ErrorInvalidState;
2059 }
2060 /* Requesting transition from WaitForResources to Loaded -
2061 is NOT tested by Khronos TS */
2062
2063 } else {
2064 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2065 eRet = OMX_ErrorBadParameter;
2066 }
2067 }
2068 /********************************/
2069 /* Current State is Invalid */
2070 /*******************************/
2071 else if (m_state == OMX_StateInvalid) {
2072 /* State Transition from Inavlid to any state */
2073 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2074 || OMX_StateIdle || OMX_StateExecuting
2075 || OMX_StatePause || OMX_StateInvalid)) {
2076 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2077 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2078 OMX_COMPONENT_GENERATE_EVENT);
2079 eRet = OMX_ErrorInvalidState;
2080 }
2081 } else if (cmd == OMX_CommandFlush) {
2082 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
2083 "with param1: %lu", param1);
2084 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2085 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2086 }
2087 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2088 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2089 }
2090 if (!sem_posted) {
2091 sem_posted = 1;
2092 DEBUG_PRINT_LOW("\n Set the Semaphore");
2093 sem_post (&m_cmd_lock);
2094 execute_omx_flush(param1);
2095 }
2096 bFlag = 0;
2097 } else if ( cmd == OMX_CommandPortEnable) {
2098 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
2099 "with param1: %lu", param1);
2100 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2101 m_inp_bEnabled = OMX_TRUE;
2102
2103 if ( (m_state == OMX_StateLoaded &&
2104 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2105 || allocate_input_done()) {
2106 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2107 OMX_COMPONENT_GENERATE_EVENT);
2108 } else {
2109 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2110 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2111 // Skip the event notification
2112 bFlag = 0;
2113 }
2114 }
2115 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2116 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2117 m_out_bEnabled = OMX_TRUE;
2118
2119 if ( (m_state == OMX_StateLoaded &&
2120 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2121 || (allocate_output_done())) {
2122 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2123 OMX_COMPONENT_GENERATE_EVENT);
2124
2125 } else {
2126 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2127 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2128 // Skip the event notification
2129 bFlag = 0;
2130 }
2131 }
2132 } else if (cmd == OMX_CommandPortDisable) {
2133 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
2134 "with param1: %lu", param1);
2135 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2136 m_inp_bEnabled = OMX_FALSE;
2137 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2138 && release_input_done()) {
2139 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2140 OMX_COMPONENT_GENERATE_EVENT);
2141 } else {
2142 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2143 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2144 if (!sem_posted) {
2145 sem_posted = 1;
2146 sem_post (&m_cmd_lock);
2147 }
2148 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2149 }
2150
2151 // Skip the event notification
2152 bFlag = 0;
2153 }
2154 }
2155 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2156 m_out_bEnabled = OMX_FALSE;
2157 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2158 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2159 && release_output_done()) {
2160 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2161 OMX_COMPONENT_GENERATE_EVENT);
2162 } else {
2163 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2164 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2165 if (!sem_posted) {
2166 sem_posted = 1;
2167 sem_post (&m_cmd_lock);
2168 }
2169 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2170 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2171 }
2172 // Skip the event notification
2173 bFlag = 0;
2174
2175 }
2176 }
2177 } else {
2178 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2179 eRet = OMX_ErrorNotImplemented;
2180 }
2181 if (eRet == OMX_ErrorNone && bFlag) {
2182 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2183 }
2184 if (!sem_posted) {
2185 sem_post(&m_cmd_lock);
2186 }
2187
2188 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002189}
2190
2191/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002192 FUNCTION
2193 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002194
Arun Menon906de572013-06-18 17:01:40 -07002195 DESCRIPTION
2196 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002197
Arun Menon906de572013-06-18 17:01:40 -07002198 PARAMETERS
2199 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002200
Arun Menon906de572013-06-18 17:01:40 -07002201 RETURN VALUE
2202 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002203
Arun Menon906de572013-06-18 17:01:40 -07002204 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002205bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2206{
Arun Menon906de572013-06-18 17:01:40 -07002207 bool bRet = false;
2208 struct v4l2_plane plane;
2209 struct v4l2_buffer v4l2_buf;
2210 struct v4l2_decoder_cmd dec;
2211 DEBUG_PRINT_LOW("in %s, flushing %d", __func__, flushType);
2212 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2213 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002214
Arun Menon906de572013-06-18 17:01:40 -07002215 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002216
Arun Menon906de572013-06-18 17:01:40 -07002217 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2218 output_flush_progress = true;
2219 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2220 } else {
2221 /* XXX: The driver/hardware does not support flushing of individual ports
2222 * in all states. So we pretty much need to flush both ports internally,
2223 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2224 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2225 * we automatically omit sending the FLUSH done for the "opposite" port. */
2226 input_flush_progress = true;
2227 output_flush_progress = true;
2228 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2229 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002230
Arun Menon906de572013-06-18 17:01:40 -07002231 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
2232 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
2233 bRet = false;
2234 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002235
Arun Menon906de572013-06-18 17:01:40 -07002236 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002237}
2238/*=========================================================================
2239FUNCTION : execute_output_flush
2240
2241DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002242Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002243
2244PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002245None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002246
2247RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002248true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002249==========================================================================*/
2250bool omx_vdec::execute_output_flush()
2251{
Arun Menon906de572013-06-18 17:01:40 -07002252 unsigned p1 = 0; // Parameter - 1
2253 unsigned p2 = 0; // Parameter - 2
2254 unsigned ident = 0;
2255 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002256
Arun Menon906de572013-06-18 17:01:40 -07002257 /*Generate FBD for all Buffers in the FTBq*/
2258 pthread_mutex_lock(&m_lock);
2259 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2260 while (m_ftb_q.m_size) {
2261 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2262 m_ftb_q.m_size,pending_output_buffers);
2263 m_ftb_q.pop_entry(&p1,&p2,&ident);
2264 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
2265 if (ident == m_fill_output_msg ) {
2266 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2267 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2268 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2269 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002270 }
Arun Menon906de572013-06-18 17:01:40 -07002271 pthread_mutex_unlock(&m_lock);
2272 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002273
Arun Menon906de572013-06-18 17:01:40 -07002274 if (arbitrary_bytes) {
2275 prev_ts = LLONG_MAX;
2276 rst_prev_ts = true;
2277 }
2278 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2279 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002280}
2281/*=========================================================================
2282FUNCTION : execute_input_flush
2283
2284DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002285Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002286
2287PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002288None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002289
2290RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002291true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002292==========================================================================*/
2293bool omx_vdec::execute_input_flush()
2294{
Arun Menon906de572013-06-18 17:01:40 -07002295 unsigned i =0;
2296 unsigned p1 = 0; // Parameter - 1
2297 unsigned p2 = 0; // Parameter - 2
2298 unsigned ident = 0;
2299 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002300
Arun Menon906de572013-06-18 17:01:40 -07002301 /*Generate EBD for all Buffers in the ETBq*/
2302 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002303
Arun Menon906de572013-06-18 17:01:40 -07002304 pthread_mutex_lock(&m_lock);
2305 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2306 while (m_etb_q.m_size) {
2307 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002308
Arun Menon906de572013-06-18 17:01:40 -07002309 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2310 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2311 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2312 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2313 pending_input_buffers++;
2314 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2315 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2316 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2317 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
2318 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2319 (OMX_BUFFERHEADERTYPE *)p1);
2320 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2321 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002322 }
Arun Menon906de572013-06-18 17:01:40 -07002323 time_stamp_dts.flush_timestamp();
2324 /*Check if Heap Buffers are to be flushed*/
2325 if (arbitrary_bytes && !(codec_config_flag)) {
2326 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2327 h264_scratch.nFilledLen = 0;
2328 nal_count = 0;
2329 look_ahead_nal = false;
2330 frame_count = 0;
2331 h264_last_au_ts = LLONG_MAX;
2332 h264_last_au_flags = 0;
2333 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2334 m_demux_entries = 0;
2335 DEBUG_PRINT_LOW("\n Initialize parser");
2336 if (m_frame_parser.mutils) {
2337 m_frame_parser.mutils->initialize_frame_checking_environment();
2338 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002339
Arun Menon906de572013-06-18 17:01:40 -07002340 while (m_input_pending_q.m_size) {
2341 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2342 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2343 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002344
Arun Menon906de572013-06-18 17:01:40 -07002345 if (psource_frame) {
2346 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2347 psource_frame = NULL;
2348 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002349
Arun Menon906de572013-06-18 17:01:40 -07002350 if (pdest_frame) {
2351 pdest_frame->nFilledLen = 0;
2352 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2353 (unsigned int)NULL);
2354 pdest_frame = NULL;
2355 }
2356 m_frame_parser.flush();
2357 } else if (codec_config_flag) {
2358 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2359 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002360 }
Arun Menon906de572013-06-18 17:01:40 -07002361 pthread_mutex_unlock(&m_lock);
2362 input_flush_progress = false;
2363 if (!arbitrary_bytes) {
2364 prev_ts = LLONG_MAX;
2365 rst_prev_ts = true;
2366 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002367#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002368 if (m_debug_timestamp) {
2369 m_timestamp_list.reset_ts_list();
2370 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002371#endif
Arun Menon906de572013-06-18 17:01:40 -07002372 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2373 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002374}
2375
2376
2377/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002378 FUNCTION
2379 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002380
Arun Menon906de572013-06-18 17:01:40 -07002381 DESCRIPTION
2382 Send the event to decoder pipe. This is needed to generate the callbacks
2383 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002384
Arun Menon906de572013-06-18 17:01:40 -07002385 PARAMETERS
2386 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002387
Arun Menon906de572013-06-18 17:01:40 -07002388 RETURN VALUE
2389 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002390
Arun Menon906de572013-06-18 17:01:40 -07002391 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002392bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002393 unsigned int p2,
2394 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002395{
Arun Menon906de572013-06-18 17:01:40 -07002396 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002397
2398
Arun Menon906de572013-06-18 17:01:40 -07002399 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002400
Arun Menon906de572013-06-18 17:01:40 -07002401 if (id == m_fill_output_msg ||
2402 id == OMX_COMPONENT_GENERATE_FBD) {
2403 m_ftb_q.insert_entry(p1,p2,id);
2404 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2405 id == OMX_COMPONENT_GENERATE_EBD ||
2406 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2407 m_etb_q.insert_entry(p1,p2,id);
2408 } else {
2409 m_cmd_q.insert_entry(p1,p2,id);
2410 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002411
Arun Menon906de572013-06-18 17:01:40 -07002412 bRet = true;
2413 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2414 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002415
Arun Menon906de572013-06-18 17:01:40 -07002416 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002417
Arun Menon906de572013-06-18 17:01:40 -07002418 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002419}
2420
2421OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2422{
Arun Menon906de572013-06-18 17:01:40 -07002423 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2424 if (!profileLevelType)
2425 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002426
Arun Menon906de572013-06-18 17:01:40 -07002427 if (profileLevelType->nPortIndex == 0) {
2428 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2429 if (profileLevelType->nProfileIndex == 0) {
2430 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2431 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002432
Arun Menon906de572013-06-18 17:01:40 -07002433 } else if (profileLevelType->nProfileIndex == 1) {
2434 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2435 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2436 } else if (profileLevelType->nProfileIndex == 2) {
2437 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2438 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2439 } else {
2440 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
2441 profileLevelType->nProfileIndex);
2442 eRet = OMX_ErrorNoMore;
2443 }
2444 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2445 if (profileLevelType->nProfileIndex == 0) {
2446 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2447 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2448 } else {
2449 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2450 eRet = OMX_ErrorNoMore;
2451 }
2452 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2453 if (profileLevelType->nProfileIndex == 0) {
2454 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2455 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2456 } else if (profileLevelType->nProfileIndex == 1) {
2457 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2458 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2459 } else {
2460 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2461 eRet = OMX_ErrorNoMore;
2462 }
2463 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2464 eRet = OMX_ErrorNoMore;
2465 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2466 if (profileLevelType->nProfileIndex == 0) {
2467 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2468 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2469 } else if (profileLevelType->nProfileIndex == 1) {
2470 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2471 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2472 } else {
2473 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2474 eRet = OMX_ErrorNoMore;
2475 }
2476 } else {
2477 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s\n", drv_ctx.kind);
2478 eRet = OMX_ErrorNoMore;
2479 }
2480 } else {
2481 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex);
2482 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002483 }
Arun Menon906de572013-06-18 17:01:40 -07002484 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002485}
2486
2487/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002488 FUNCTION
2489 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002490
Arun Menon906de572013-06-18 17:01:40 -07002491 DESCRIPTION
2492 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002493
Arun Menon906de572013-06-18 17:01:40 -07002494 PARAMETERS
2495 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002496
Arun Menon906de572013-06-18 17:01:40 -07002497 RETURN VALUE
2498 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002499
Arun Menon906de572013-06-18 17:01:40 -07002500 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002501OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002502 OMX_IN OMX_INDEXTYPE paramIndex,
2503 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002504{
2505 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2506
2507 DEBUG_PRINT_LOW("get_parameter: \n");
Arun Menon906de572013-06-18 17:01:40 -07002508 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002509 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2510 return OMX_ErrorInvalidState;
2511 }
Arun Menon906de572013-06-18 17:01:40 -07002512 if (paramData == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002513 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2514 return OMX_ErrorBadParameter;
2515 }
Arun Menon906de572013-06-18 17:01:40 -07002516 switch ((unsigned long)paramIndex) {
2517 case OMX_IndexParamPortDefinition: {
2518 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2519 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2520 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2521 eRet = update_portdef(portDefn);
2522 if (eRet == OMX_ErrorNone)
2523 m_port_def = *portDefn;
2524 break;
2525 }
2526 case OMX_IndexParamVideoInit: {
2527 OMX_PORT_PARAM_TYPE *portParamType =
2528 (OMX_PORT_PARAM_TYPE *) paramData;
2529 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002530
Arun Menon906de572013-06-18 17:01:40 -07002531 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2532 portParamType->nSize = sizeof(portParamType);
2533 portParamType->nPorts = 2;
2534 portParamType->nStartPortNumber = 0;
2535 break;
2536 }
2537 case OMX_IndexParamVideoPortFormat: {
2538 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2539 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2540 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002541
Arun Menon906de572013-06-18 17:01:40 -07002542 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2543 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002544
Arun Menon906de572013-06-18 17:01:40 -07002545 if (0 == portFmt->nPortIndex) {
2546 if (0 == portFmt->nIndex) {
2547 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2548 portFmt->eCompressionFormat = eCompressionFormat;
2549 } else {
2550 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2551 " NoMore compression formats\n");
2552 eRet = OMX_ErrorNoMore;
2553 }
2554 } else if (1 == portFmt->nPortIndex) {
2555 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002556
Arun Menon906de572013-06-18 17:01:40 -07002557 if (0 == portFmt->nIndex)
2558 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2559 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2560 else if (1 == portFmt->nIndex)
2561 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2562 else {
2563 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2564 " NoMore Color formats\n");
2565 eRet = OMX_ErrorNoMore;
2566 }
2567 DEBUG_PRINT_LOW("returning %d\n", portFmt->eColorFormat);
2568 } else {
2569 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2570 (int)portFmt->nPortIndex);
2571 eRet = OMX_ErrorBadPortIndex;
2572 }
2573 break;
2574 }
2575 /*Component should support this port definition*/
2576 case OMX_IndexParamAudioInit: {
2577 OMX_PORT_PARAM_TYPE *audioPortParamType =
2578 (OMX_PORT_PARAM_TYPE *) paramData;
2579 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2580 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2581 audioPortParamType->nSize = sizeof(audioPortParamType);
2582 audioPortParamType->nPorts = 0;
2583 audioPortParamType->nStartPortNumber = 0;
2584 break;
2585 }
2586 /*Component should support this port definition*/
2587 case OMX_IndexParamImageInit: {
2588 OMX_PORT_PARAM_TYPE *imagePortParamType =
2589 (OMX_PORT_PARAM_TYPE *) paramData;
2590 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2591 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2592 imagePortParamType->nSize = sizeof(imagePortParamType);
2593 imagePortParamType->nPorts = 0;
2594 imagePortParamType->nStartPortNumber = 0;
2595 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002596
Arun Menon906de572013-06-18 17:01:40 -07002597 }
2598 /*Component should support this port definition*/
2599 case OMX_IndexParamOtherInit: {
2600 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2601 paramIndex);
2602 eRet =OMX_ErrorUnsupportedIndex;
2603 break;
2604 }
2605 case OMX_IndexParamStandardComponentRole: {
2606 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2607 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2608 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2609 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002610
Arun Menon906de572013-06-18 17:01:40 -07002611 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2612 paramIndex);
2613 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2614 OMX_MAX_STRINGNAME_SIZE);
2615 break;
2616 }
2617 /* Added for parameter test */
2618 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002619
Arun Menon906de572013-06-18 17:01:40 -07002620 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2621 (OMX_PRIORITYMGMTTYPE *) paramData;
2622 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2623 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2624 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002625
Arun Menon906de572013-06-18 17:01:40 -07002626 break;
2627 }
2628 /* Added for parameter test */
2629 case OMX_IndexParamCompBufferSupplier: {
2630 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2631 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2632 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002633
Arun Menon906de572013-06-18 17:01:40 -07002634 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2635 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2636 if (0 == bufferSupplierType->nPortIndex)
2637 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2638 else if (1 == bufferSupplierType->nPortIndex)
2639 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2640 else
2641 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002642
2643
Arun Menon906de572013-06-18 17:01:40 -07002644 break;
2645 }
2646 case OMX_IndexParamVideoAvc: {
2647 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2648 paramIndex);
2649 break;
2650 }
2651 case OMX_IndexParamVideoH263: {
2652 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2653 paramIndex);
2654 break;
2655 }
2656 case OMX_IndexParamVideoMpeg4: {
2657 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2658 paramIndex);
2659 break;
2660 }
2661 case OMX_IndexParamVideoMpeg2: {
2662 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2663 paramIndex);
2664 break;
2665 }
2666 case OMX_IndexParamVideoProfileLevelQuerySupported: {
2667 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2668 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2669 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2670 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2671 break;
2672 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002673#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002674 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
2675 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2676 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2677 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002678
Arun Menon906de572013-06-18 17:01:40 -07002679 if (secure_mode) {
2680 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2681 GRALLOC_USAGE_PRIVATE_UNCACHED);
2682 } else {
2683 nativeBuffersUsage->nUsage =
2684 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2685 GRALLOC_USAGE_PRIVATE_UNCACHED);
2686 }
2687 } else {
2688 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
2689 eRet = OMX_ErrorBadParameter;
2690 }
2691 }
2692 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002693#endif
2694
Arun Menon906de572013-06-18 17:01:40 -07002695 default: {
2696 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2697 eRet =OMX_ErrorUnsupportedIndex;
2698 }
2699
Shalaj Jain273b3e02012-06-22 19:08:03 -07002700 }
2701
Arun Menon906de572013-06-18 17:01:40 -07002702 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
2703 drv_ctx.video_resolution.frame_width,
2704 drv_ctx.video_resolution.frame_height,
2705 drv_ctx.video_resolution.stride,
2706 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002707
Arun Menon906de572013-06-18 17:01:40 -07002708 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002709}
2710
2711#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2712OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2713{
2714 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2715 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2716 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2717
Arun Menon906de572013-06-18 17:01:40 -07002718 if ((params == NULL) ||
2719 (params->nativeBuffer == NULL) ||
2720 (params->nativeBuffer->handle == NULL) ||
2721 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002722 return OMX_ErrorBadParameter;
2723 m_use_android_native_buffers = OMX_TRUE;
2724 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2725 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002726 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 -07002727 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002728 if (!secure_mode) {
2729 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002730 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002731 if (buffer == MAP_FAILED) {
2732 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2733 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002734 }
2735 }
2736 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2737 } else {
2738 eRet = OMX_ErrorBadParameter;
2739 }
2740 return eRet;
2741}
2742#endif
2743/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002744 FUNCTION
2745 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002746
Arun Menon906de572013-06-18 17:01:40 -07002747 DESCRIPTION
2748 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002749
Arun Menon906de572013-06-18 17:01:40 -07002750 PARAMETERS
2751 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002752
Arun Menon906de572013-06-18 17:01:40 -07002753 RETURN VALUE
2754 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002755
Arun Menon906de572013-06-18 17:01:40 -07002756 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002757OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002758 OMX_IN OMX_INDEXTYPE paramIndex,
2759 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002760{
2761 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002762 int ret=0;
2763 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002764 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002765 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
2766 return OMX_ErrorInvalidState;
2767 }
Arun Menon906de572013-06-18 17:01:40 -07002768 if (paramData == NULL) {
2769 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
2770 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002771 }
Arun Menon906de572013-06-18 17:01:40 -07002772 if ((m_state != OMX_StateLoaded) &&
2773 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2774 (m_out_bEnabled == OMX_TRUE) &&
2775 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2776 (m_inp_bEnabled == OMX_TRUE)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002777 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
2778 return OMX_ErrorIncorrectStateOperation;
2779 }
Arun Menon906de572013-06-18 17:01:40 -07002780 switch ((unsigned long)paramIndex) {
2781 case OMX_IndexParamPortDefinition: {
2782 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2783 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2784 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2785 //been called.
2786 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
2787 (int)portDefn->format.video.nFrameHeight,
2788 (int)portDefn->format.video.nFrameWidth);
2789 if (OMX_DirOutput == portDefn->eDir) {
2790 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
2791 m_display_id = portDefn->format.video.pNativeWindow;
2792 unsigned int buffer_size;
2793 if (!client_buffers.get_buffer_req(buffer_size)) {
2794 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
2795 eRet = OMX_ErrorBadParameter;
2796 } else {
2797 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
2798 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
2799 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
2800 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
2801 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
2802 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
2803 drv_ctx.extradata_info.buffer_size;
2804 eRet = set_buffer_req(&drv_ctx.op_buf);
2805 if (eRet == OMX_ErrorNone)
2806 m_port_def = *portDefn;
2807 } else {
2808 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
2809 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
2810 portDefn->nBufferCountActual, portDefn->nBufferSize);
2811 eRet = OMX_ErrorBadParameter;
2812 }
2813 }
2814 } else if (OMX_DirInput == portDefn->eDir) {
2815 bool port_format_changed = false;
2816 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
2817 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
2818 // Frame rate only should be set if this is a "known value" or to
2819 // activate ts prediction logic (arbitrary mode only) sending input
2820 // timestamps with max value (LLONG_MAX).
2821 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
2822 portDefn->format.video.xFramerate >> 16);
2823 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
2824 drv_ctx.frame_rate.fps_denominator);
2825 if (!drv_ctx.frame_rate.fps_numerator) {
2826 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
2827 drv_ctx.frame_rate.fps_numerator = 30;
2828 }
2829 if (drv_ctx.frame_rate.fps_denominator)
2830 drv_ctx.frame_rate.fps_numerator = (int)
2831 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
2832 drv_ctx.frame_rate.fps_denominator = 1;
2833 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
2834 drv_ctx.frame_rate.fps_numerator;
2835 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
2836 frm_int, drv_ctx.frame_rate.fps_numerator /
2837 (float)drv_ctx.frame_rate.fps_denominator);
2838 }
2839 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
2840 if (drv_ctx.video_resolution.frame_height !=
2841 portDefn->format.video.nFrameHeight ||
2842 drv_ctx.video_resolution.frame_width !=
2843 portDefn->format.video.nFrameWidth) {
2844 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
2845 portDefn->format.video.nFrameWidth,
2846 portDefn->format.video.nFrameHeight);
2847 port_format_changed = true;
2848 if (portDefn->format.video.nFrameHeight != 0x0 &&
2849 portDefn->format.video.nFrameWidth != 0x0) {
2850 update_resolution(portDefn->format.video.nFrameWidth,
2851 portDefn->format.video.nFrameHeight,
2852 portDefn->format.video.nFrameWidth,
2853 portDefn->format.video.nFrameHeight);
2854 eRet = is_video_session_supported();
2855 if (eRet)
2856 break;
2857 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2858 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2859 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2860 fmt.fmt.pix_mp.pixelformat = output_capability;
2861 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);
2862 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2863 if (ret) {
2864 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2865 eRet = OMX_ErrorUnsupportedSetting;
2866 } else
2867 eRet = get_buffer_req(&drv_ctx.op_buf);
2868 }
2869 }
2870 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
2871 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
2872 port_format_changed = true;
2873 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
2874 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
2875 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
2876 (~(buffer_prop->alignment - 1));
2877 eRet = set_buffer_req(buffer_prop);
2878 }
2879 if (false == port_format_changed) {
2880 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
2881 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
2882 portDefn->nBufferCountActual, portDefn->nBufferSize);
2883 eRet = OMX_ErrorBadParameter;
2884 }
2885 } else if (portDefn->eDir == OMX_DirMax) {
2886 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
2887 (int)portDefn->nPortIndex);
2888 eRet = OMX_ErrorBadPortIndex;
2889 }
2890 }
2891 break;
2892 case OMX_IndexParamVideoPortFormat: {
2893 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2894 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2895 int ret=0;
2896 struct v4l2_format fmt;
2897 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
2898 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002899
Arun Menon906de572013-06-18 17:01:40 -07002900 if (1 == portFmt->nPortIndex) {
2901 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2902 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2903 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2904 fmt.fmt.pix_mp.pixelformat = capture_capability;
2905 enum vdec_output_fromat op_format;
2906 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
2907 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
2908 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
2909 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
2910 else if (portFmt->eColorFormat ==
2911 (OMX_COLOR_FORMATTYPE)
2912 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
2913 op_format = VDEC_YUV_FORMAT_TILE_4x2;
2914 else
2915 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002916
Arun Menon906de572013-06-18 17:01:40 -07002917 if (eRet == OMX_ErrorNone) {
2918 drv_ctx.output_format = op_format;
2919 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2920 if (ret) {
2921 DEBUG_PRINT_ERROR("\n Set output format failed");
2922 eRet = OMX_ErrorUnsupportedSetting;
2923 /*TODO: How to handle this case */
2924 } else {
2925 eRet = get_buffer_req(&drv_ctx.op_buf);
2926 }
2927 }
2928 if (eRet == OMX_ErrorNone) {
2929 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
2930 DEBUG_PRINT_ERROR("\n Set color format failed");
2931 eRet = OMX_ErrorBadParameter;
2932 }
2933 }
2934 }
2935 }
2936 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002937
Arun Menon906de572013-06-18 17:01:40 -07002938 case OMX_QcomIndexPortDefn: {
2939 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
2940 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
2941 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
2942 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002943
Arun Menon906de572013-06-18 17:01:40 -07002944 /* Input port */
2945 if (portFmt->nPortIndex == 0) {
2946 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
2947 if (secure_mode) {
2948 arbitrary_bytes = false;
2949 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
2950 eRet = OMX_ErrorUnsupportedSetting;
2951 } else {
2952 arbitrary_bytes = true;
2953 }
2954 } else if (portFmt->nFramePackingFormat ==
2955 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
2956 arbitrary_bytes = false;
2957 } else {
2958 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
2959 portFmt->nFramePackingFormat);
2960 eRet = OMX_ErrorUnsupportedSetting;
2961 }
2962 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
2963 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
2964 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
2965 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
2966 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
2967 m_out_mem_region_smi = OMX_TRUE;
2968 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
2969 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
2970 m_use_output_pmem = OMX_TRUE;
2971 }
2972 }
2973 }
2974 }
2975 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002976
Arun Menon906de572013-06-18 17:01:40 -07002977 case OMX_IndexParamStandardComponentRole: {
2978 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2979 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2980 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
2981 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002982
Arun Menon906de572013-06-18 17:01:40 -07002983 if ((m_state == OMX_StateLoaded)&&
2984 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
2985 DEBUG_PRINT_LOW("Set Parameter called in valid state");
2986 } else {
2987 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
2988 return OMX_ErrorIncorrectStateOperation;
2989 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002990
Arun Menon906de572013-06-18 17:01:40 -07002991 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2992 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2993 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
2994 } else {
2995 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
2996 eRet =OMX_ErrorUnsupportedSetting;
2997 }
2998 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2999 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3000 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3001 } else {
3002 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3003 eRet = OMX_ErrorUnsupportedSetting;
3004 }
3005 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3006 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3007 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3008 } else {
3009 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3010 eRet =OMX_ErrorUnsupportedSetting;
3011 }
3012 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3013 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3014 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3015 } else {
3016 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3017 eRet = OMX_ErrorUnsupportedSetting;
3018 }
3019 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3020 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3021 ) {
3022 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3023 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3024 } else {
3025 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3026 eRet =OMX_ErrorUnsupportedSetting;
3027 }
3028 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3029 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3030 ) {
3031 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3032 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3033 } else {
3034 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3035 eRet =OMX_ErrorUnsupportedSetting;
3036 }
3037 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3038 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3039 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3040 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3041 } else {
3042 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3043 eRet = OMX_ErrorUnsupportedSetting;
3044 }
3045 } else {
3046 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3047 eRet = OMX_ErrorInvalidComponentName;
3048 }
3049 break;
3050 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003051
Arun Menon906de572013-06-18 17:01:40 -07003052 case OMX_IndexParamPriorityMgmt: {
3053 if (m_state != OMX_StateLoaded) {
3054 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3055 return OMX_ErrorIncorrectStateOperation;
3056 }
3057 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
3058 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
3059 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003060
Arun Menon906de572013-06-18 17:01:40 -07003061 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
3062 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003063
Arun Menon906de572013-06-18 17:01:40 -07003064 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3065 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003066
Arun Menon906de572013-06-18 17:01:40 -07003067 break;
3068 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003069
Arun Menon906de572013-06-18 17:01:40 -07003070 case OMX_IndexParamCompBufferSupplier: {
3071 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3072 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3073 bufferSupplierType->eBufferSupplier);
3074 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3075 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003076
Arun Menon906de572013-06-18 17:01:40 -07003077 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003078
Arun Menon906de572013-06-18 17:01:40 -07003079 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003080
Arun Menon906de572013-06-18 17:01:40 -07003081 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003082
Arun Menon906de572013-06-18 17:01:40 -07003083 }
3084 case OMX_IndexParamVideoAvc: {
3085 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3086 paramIndex);
3087 break;
3088 }
3089 case OMX_IndexParamVideoH263: {
3090 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3091 paramIndex);
3092 break;
3093 }
3094 case OMX_IndexParamVideoMpeg4: {
3095 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3096 paramIndex);
3097 break;
3098 }
3099 case OMX_IndexParamVideoMpeg2: {
3100 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3101 paramIndex);
3102 break;
3103 }
3104 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3105 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3106 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3107 struct v4l2_control control;
3108 int pic_order,rc=0;
3109 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3110 pictureOrder->eOutputPictureOrder);
3111 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3112 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3113 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3114 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3115 time_stamp_dts.set_timestamp_reorder_mode(false);
3116 } else
3117 eRet = OMX_ErrorBadParameter;
3118 if (eRet == OMX_ErrorNone) {
3119 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3120 control.value = pic_order;
3121 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3122 if (rc) {
3123 DEBUG_PRINT_ERROR("\n Set picture order failed");
3124 eRet = OMX_ErrorUnsupportedSetting;
3125 }
3126 }
3127 break;
3128 }
3129 case OMX_QcomIndexParamConcealMBMapExtraData:
3130 if (!secure_mode)
3131 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3132 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3133 else {
3134 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3135 eRet = OMX_ErrorUnsupportedSetting;
3136 }
3137 break;
3138 case OMX_QcomIndexParamFrameInfoExtraData: {
3139 if (!secure_mode)
3140 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3141 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3142 else {
3143 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3144 eRet = OMX_ErrorUnsupportedSetting;
3145 }
3146 break;
3147 }
3148 case OMX_QcomIndexParamInterlaceExtraData:
3149 if (!secure_mode)
3150 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3151 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3152 else {
3153 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3154 eRet = OMX_ErrorUnsupportedSetting;
3155 }
3156 break;
3157 case OMX_QcomIndexParamH264TimeInfo:
3158 if (!secure_mode)
3159 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3160 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3161 else {
3162 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3163 eRet = OMX_ErrorUnsupportedSetting;
3164 }
3165 break;
3166 case OMX_QcomIndexParamVideoDivx: {
3167 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3168 }
3169 break;
3170 case OMX_QcomIndexPlatformPvt: {
3171 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3172 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3173 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3174 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3175 eRet = OMX_ErrorUnsupportedSetting;
3176 } else {
3177 m_out_pvt_entry_pmem = OMX_TRUE;
3178 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3179 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3180 m_use_output_pmem = OMX_TRUE;
3181 }
3182 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003183
Arun Menon906de572013-06-18 17:01:40 -07003184 }
3185 break;
3186 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3187 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3188 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3189 struct v4l2_control control;
3190 int rc;
3191 drv_ctx.idr_only_decoding = 1;
3192 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3193 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3194 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3195 if (rc) {
3196 DEBUG_PRINT_ERROR("\n Set picture order failed");
3197 eRet = OMX_ErrorUnsupportedSetting;
3198 } else {
3199 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3200 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3201 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3202 if (rc) {
3203 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3204 eRet = OMX_ErrorUnsupportedSetting;
3205 }
3206 /*Setting sync frame decoding on driver might change buffer
3207 * requirements so update them here*/
3208 if (get_buffer_req(&drv_ctx.ip_buf)) {
3209 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer i/p requirements");
3210 eRet = OMX_ErrorUnsupportedSetting;
3211 }
3212 if (get_buffer_req(&drv_ctx.op_buf)) {
3213 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer o/p requirements");
3214 eRet = OMX_ErrorUnsupportedSetting;
3215 }
3216 }
3217 }
3218 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003219
Arun Menon906de572013-06-18 17:01:40 -07003220 case OMX_QcomIndexParamIndexExtraDataType: {
3221 if (!secure_mode) {
3222 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3223 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3224 (extradataIndexType->bEnabled == OMX_TRUE) &&
3225 (extradataIndexType->nPortIndex == 1)) {
3226 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
3227 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003228
Arun Menon906de572013-06-18 17:01:40 -07003229 }
3230 }
3231 }
3232 break;
3233 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003234#ifndef SMOOTH_STREAMING_DISABLED
Arun Menon906de572013-06-18 17:01:40 -07003235 struct v4l2_control control;
3236 struct v4l2_format fmt;
3237 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3238 control.value = 1;
3239 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3240 if (rc < 0) {
3241 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3242 eRet = OMX_ErrorHardware;
3243 }
Arun Menonbc0922f2013-06-24 13:02:15 -07003244#else
Arun Menon906de572013-06-18 17:01:40 -07003245 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003246#endif
Arun Menon906de572013-06-18 17:01:40 -07003247 }
3248 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003249#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003250 /* Need to allow following two set_parameters even in Idle
3251 * state. This is ANDROID architecture which is not in sync
3252 * with openmax standard. */
3253 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3254 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3255 if (enableNativeBuffers) {
3256 m_enable_android_native_buffers = enableNativeBuffers->enable;
3257 }
3258 }
3259 break;
3260 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3261 eRet = use_android_native_buffer(hComp, paramData);
3262 }
3263 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003264#endif
Arun Menon906de572013-06-18 17:01:40 -07003265 case OMX_QcomIndexParamEnableTimeStampReorder: {
3266 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3267 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3268 if (reorder->bEnable == OMX_TRUE) {
3269 frm_int =0;
3270 time_stamp_dts.set_timestamp_reorder_mode(true);
3271 } else
3272 time_stamp_dts.set_timestamp_reorder_mode(false);
3273 } else {
3274 time_stamp_dts.set_timestamp_reorder_mode(false);
3275 if (reorder->bEnable == OMX_TRUE) {
3276 eRet = OMX_ErrorUnsupportedSetting;
3277 }
3278 }
3279 }
3280 break;
3281 case OMX_IndexParamVideoProfileLevelCurrent: {
3282 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3283 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3284 if (pParam) {
3285 m_profile_lvl.eProfile = pParam->eProfile;
3286 m_profile_lvl.eLevel = pParam->eLevel;
3287 }
3288 break;
Arun Menon888aa852013-05-30 11:24:42 -07003289
Arun Menon906de572013-06-18 17:01:40 -07003290 }
3291 default: {
3292 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3293 eRet = OMX_ErrorUnsupportedIndex;
3294 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003295 }
Arun Menon906de572013-06-18 17:01:40 -07003296 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003297}
3298
3299/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003300 FUNCTION
3301 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003302
Arun Menon906de572013-06-18 17:01:40 -07003303 DESCRIPTION
3304 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003305
Arun Menon906de572013-06-18 17:01:40 -07003306 PARAMETERS
3307 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003308
Arun Menon906de572013-06-18 17:01:40 -07003309 RETURN VALUE
3310 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003311
Arun Menon906de572013-06-18 17:01:40 -07003312 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003313OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003314 OMX_IN OMX_INDEXTYPE configIndex,
3315 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003316{
Arun Menon906de572013-06-18 17:01:40 -07003317 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003318
Arun Menon906de572013-06-18 17:01:40 -07003319 if (m_state == OMX_StateInvalid) {
3320 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003321 return OMX_ErrorInvalidState;
3322 }
Arun Menon906de572013-06-18 17:01:40 -07003323
3324 switch ((unsigned long)configIndex) {
3325 case OMX_QcomIndexConfigInterlaced: {
3326 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3327 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3328 if (configFmt->nPortIndex == 1) {
3329 if (configFmt->nIndex == 0) {
3330 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3331 } else if (configFmt->nIndex == 1) {
3332 configFmt->eInterlaceType =
3333 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3334 } else if (configFmt->nIndex == 2) {
3335 configFmt->eInterlaceType =
3336 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3337 } else {
3338 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3339 " NoMore Interlaced formats\n");
3340 eRet = OMX_ErrorNoMore;
3341 }
3342
3343 } else {
3344 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3345 (int)configFmt->nPortIndex);
3346 eRet = OMX_ErrorBadPortIndex;
3347 }
3348 break;
3349 }
3350 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3351 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3352 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3353 decoderinstances->nNumOfInstances = 16;
3354 /*TODO: How to handle this case */
3355 break;
3356 }
3357 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3358 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3359 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3360 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3361 h264_parser->get_frame_pack_data(configFmt);
3362 } else {
3363 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3364 }
3365 break;
3366 }
3367 case OMX_IndexConfigCommonOutputCrop: {
3368 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3369 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3370 break;
3371 }
3372 default: {
3373 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3374 eRet = OMX_ErrorBadParameter;
3375 }
3376
Shalaj Jain273b3e02012-06-22 19:08:03 -07003377 }
Arun Menon906de572013-06-18 17:01:40 -07003378
3379 return eRet;
3380}
3381
3382/* ======================================================================
3383 FUNCTION
3384 omx_vdec::SetConfig
3385
3386 DESCRIPTION
3387 OMX Set Config method implementation
3388
3389 PARAMETERS
3390 <TBD>.
3391
3392 RETURN VALUE
3393 OMX Error None if successful.
3394 ========================================================================== */
3395OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3396 OMX_IN OMX_INDEXTYPE configIndex,
3397 OMX_IN OMX_PTR configData)
3398{
3399 if (m_state == OMX_StateInvalid) {
3400 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3401 return OMX_ErrorInvalidState;
3402 }
3403
3404 OMX_ERRORTYPE ret = OMX_ErrorNone;
3405 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3406
3407 DEBUG_PRINT_LOW("\n Set Config Called");
3408
3409 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3410 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3411 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3412 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
3413 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3414 OMX_U32 extra_size;
3415 // Parsing done here for the AVC atom is definitely not generic
3416 // Currently this piece of code is working, but certainly
3417 // not tested with all .mp4 files.
3418 // Incase of failure, we might need to revisit this
3419 // for a generic piece of code.
3420
3421 // Retrieve size of NAL length field
3422 // byte #4 contains the size of NAL lenght field
3423 nal_length = (config->pData[4] & 0x03) + 1;
3424
3425 extra_size = 0;
3426 if (nal_length > 2) {
3427 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3428 extra_size = (nal_length - 2) * 2;
3429 }
3430
3431 // SPS starts from byte #6
3432 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3433 OMX_U8 *pDestBuf;
3434 m_vendor_config.nPortIndex = config->nPortIndex;
3435
3436 // minus 6 --> SPS starts from byte #6
3437 // minus 1 --> picture param set byte to be ignored from avcatom
3438 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3439 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3440 OMX_U32 len;
3441 OMX_U8 index = 0;
3442 // case where SPS+PPS is sent as part of set_config
3443 pDestBuf = m_vendor_config.pData;
3444
3445 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
3446 m_vendor_config.nPortIndex,
3447 m_vendor_config.nDataSize,
3448 m_vendor_config.pData);
3449 while (index < 2) {
3450 uint8 *psize;
3451 len = *pSrcBuf;
3452 len = len << 8;
3453 len |= *(pSrcBuf + 1);
3454 psize = (uint8 *) & len;
3455 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3456 for (unsigned int i = 0; i < nal_length; i++) {
3457 pDestBuf[i] = psize[nal_length - 1 - i];
3458 }
3459 //memcpy(pDestBuf,pSrcBuf,(len+2));
3460 pDestBuf += len + nal_length;
3461 pSrcBuf += len + 2;
3462 index++;
3463 pSrcBuf++; // skip picture param set
3464 len = 0;
3465 }
3466 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3467 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3468 m_vendor_config.nPortIndex = config->nPortIndex;
3469 m_vendor_config.nDataSize = config->nDataSize;
3470 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3471 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3472 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3473 if (m_vendor_config.pData) {
3474 free(m_vendor_config.pData);
3475 m_vendor_config.pData = NULL;
3476 m_vendor_config.nDataSize = 0;
3477 }
3478
3479 if (((*((OMX_U32 *) config->pData)) &
3480 VC1_SP_MP_START_CODE_MASK) ==
3481 VC1_SP_MP_START_CODE) {
3482 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3483 m_vendor_config.nPortIndex = config->nPortIndex;
3484 m_vendor_config.nDataSize = config->nDataSize;
3485 m_vendor_config.pData =
3486 (OMX_U8 *) malloc(config->nDataSize);
3487 memcpy(m_vendor_config.pData, config->pData,
3488 config->nDataSize);
3489 m_vc1_profile = VC1_SP_MP_RCV;
3490 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
3491 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3492 m_vendor_config.nPortIndex = config->nPortIndex;
3493 m_vendor_config.nDataSize = config->nDataSize;
3494 m_vendor_config.pData =
3495 (OMX_U8 *) malloc((config->nDataSize));
3496 memcpy(m_vendor_config.pData, config->pData,
3497 config->nDataSize);
3498 m_vc1_profile = VC1_AP;
3499 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
3500 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3501 m_vendor_config.nPortIndex = config->nPortIndex;
3502 m_vendor_config.nDataSize = config->nDataSize;
3503 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3504 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3505 m_vc1_profile = VC1_SP_MP_RCV;
3506 } else {
3507 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3508 }
3509 }
3510 return ret;
3511 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3512 struct v4l2_control temp;
3513 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3514
3515 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3516 switch (pNal->nNaluBytes) {
3517 case 0:
3518 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3519 break;
3520 case 2:
3521 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3522 break;
3523 case 4:
3524 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3525 break;
3526 default:
3527 return OMX_ErrorUnsupportedSetting;
3528 }
3529
3530 if (!arbitrary_bytes) {
3531 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3532 * with start code, so only need to notify driver in frame by frame mode */
3533 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3534 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3535 return OMX_ErrorHardware;
3536 }
3537 }
3538
3539 nal_length = pNal->nNaluBytes;
3540 m_frame_parser.init_nal_length(nal_length);
3541
3542 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
3543 return ret;
3544 } else if (configIndex == OMX_IndexVendorVideoFrameRate) {
3545 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
3546 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps);
3547
3548 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3549 if (config->bEnabled) {
3550 if ((config->nFps >> 16) > 0) {
3551 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d",
3552 config->nFps >> 16);
3553 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3554 drv_ctx.frame_rate.fps_denominator);
3555
3556 if (!drv_ctx.frame_rate.fps_numerator) {
3557 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3558 drv_ctx.frame_rate.fps_numerator = 30;
3559 }
3560
3561 if (drv_ctx.frame_rate.fps_denominator) {
3562 drv_ctx.frame_rate.fps_numerator = (int)
3563 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3564 }
3565
3566 drv_ctx.frame_rate.fps_denominator = 1;
3567 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3568 drv_ctx.frame_rate.fps_numerator;
3569
3570 struct v4l2_outputparm oparm;
3571 /*XXX: we're providing timing info as seconds per frame rather than frames
3572 * per second.*/
3573 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3574 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3575
3576 struct v4l2_streamparm sparm;
3577 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3578 sparm.parm.output = oparm;
3579 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3580 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3581 performance might be affected");
3582 ret = OMX_ErrorHardware;
3583 }
3584 client_set_fps = true;
3585 } else {
3586 DEBUG_PRINT_ERROR("Frame rate not supported.");
3587 ret = OMX_ErrorUnsupportedSetting;
3588 }
3589 } else {
3590 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3591 client_set_fps = false;
3592 }
3593 } else {
3594 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3595 (int)config->nPortIndex);
3596 ret = OMX_ErrorBadPortIndex;
3597 }
3598
3599 return ret;
3600 }
3601
3602 return OMX_ErrorNotImplemented;
3603}
3604
3605/* ======================================================================
3606 FUNCTION
3607 omx_vdec::GetExtensionIndex
3608
3609 DESCRIPTION
3610 OMX GetExtensionIndex method implementaion. <TBD>
3611
3612 PARAMETERS
3613 <TBD>.
3614
3615 RETURN VALUE
3616 OMX Error None if everything successful.
3617
3618 ========================================================================== */
3619OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3620 OMX_IN OMX_STRING paramName,
3621 OMX_OUT OMX_INDEXTYPE* indexType)
3622{
3623 if (m_state == OMX_StateInvalid) {
3624 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3625 return OMX_ErrorInvalidState;
3626 } else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3627 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3628 } else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003629 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3630 }
3631#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003632 else if (!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003633 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Arun Menon906de572013-06-18 17:01:40 -07003634 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003635 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Arun Menon906de572013-06-18 17:01:40 -07003636 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003637 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3638 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Arun Menon906de572013-06-18 17:01:40 -07003639 } else if (!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003640 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3641 }
3642#endif
Arun Menon906de572013-06-18 17:01:40 -07003643 else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003644 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3645 return OMX_ErrorNotImplemented;
3646 }
3647 return OMX_ErrorNone;
3648}
3649
3650/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003651 FUNCTION
3652 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07003653
Arun Menon906de572013-06-18 17:01:40 -07003654 DESCRIPTION
3655 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003656
Arun Menon906de572013-06-18 17:01:40 -07003657 PARAMETERS
3658 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003659
Arun Menon906de572013-06-18 17:01:40 -07003660 RETURN VALUE
3661 Error None if everything is successful.
3662 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003663OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003664 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003665{
Arun Menon906de572013-06-18 17:01:40 -07003666 *state = m_state;
3667 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
3668 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003669}
3670
3671/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003672 FUNCTION
3673 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07003674
Arun Menon906de572013-06-18 17:01:40 -07003675 DESCRIPTION
3676 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003677
Arun Menon906de572013-06-18 17:01:40 -07003678 PARAMETERS
3679 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003680
Arun Menon906de572013-06-18 17:01:40 -07003681 RETURN VALUE
3682 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003683
Arun Menon906de572013-06-18 17:01:40 -07003684 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003685OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003686 OMX_IN OMX_U32 port,
3687 OMX_IN OMX_HANDLETYPE peerComponent,
3688 OMX_IN OMX_U32 peerPort,
3689 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003690{
Arun Menon906de572013-06-18 17:01:40 -07003691 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3692 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003693}
3694
3695/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003696 FUNCTION
3697 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07003698
Arun Menon906de572013-06-18 17:01:40 -07003699 DESCRIPTION
3700 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07003701
Arun Menon906de572013-06-18 17:01:40 -07003702 PARAMETERS
3703 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003704
Arun Menon906de572013-06-18 17:01:40 -07003705 RETURN VALUE
3706 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07003707
Arun Menon906de572013-06-18 17:01:40 -07003708 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003709OMX_ERRORTYPE omx_vdec::allocate_extradata()
3710{
3711#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003712 if (drv_ctx.extradata_info.buffer_size) {
3713 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
3714 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3715 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3716 free_ion_memory(&drv_ctx.extradata_info.ion);
3717 }
3718 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
3719 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
3720 drv_ctx.extradata_info.size, 4096,
3721 &drv_ctx.extradata_info.ion.ion_alloc_data,
3722 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
3723 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
3724 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
3725 return OMX_ErrorInsufficientResources;
3726 }
3727 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
3728 drv_ctx.extradata_info.size,
3729 PROT_READ|PROT_WRITE, MAP_SHARED,
3730 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
3731 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
3732 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
3733 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3734 free_ion_memory(&drv_ctx.extradata_info.ion);
3735 return OMX_ErrorInsufficientResources;
3736 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003737 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003738#endif
Arun Menon906de572013-06-18 17:01:40 -07003739 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003740}
3741
Arun Menon906de572013-06-18 17:01:40 -07003742void omx_vdec::free_extradata()
3743{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003744#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003745 if (drv_ctx.extradata_info.uaddr) {
3746 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3747 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3748 free_ion_memory(&drv_ctx.extradata_info.ion);
3749 }
3750 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003751#endif
3752}
3753
Shalaj Jain273b3e02012-06-22 19:08:03 -07003754OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07003755 OMX_IN OMX_HANDLETYPE hComp,
3756 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3757 OMX_IN OMX_U32 port,
3758 OMX_IN OMX_PTR appData,
3759 OMX_IN OMX_U32 bytes,
3760 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003761{
Arun Menon906de572013-06-18 17:01:40 -07003762 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3763 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
3764 unsigned i= 0; // Temporary counter
3765 struct vdec_setbuffer_cmd setbuffers;
3766 OMX_PTR privateAppData = NULL;
3767 private_handle_t *handle = NULL;
3768 OMX_U8 *buff = buffer;
3769 struct v4l2_buffer buf;
3770 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3771 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003772
Arun Menon906de572013-06-18 17:01:40 -07003773 if (!m_out_mem_ptr) {
3774 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
3775 eRet = allocate_output_headers();
3776 if (eRet == OMX_ErrorNone)
3777 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07003778 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003779
Arun Menon906de572013-06-18 17:01:40 -07003780 if (eRet == OMX_ErrorNone) {
3781 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
3782 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
3783 break;
3784 }
3785 }
3786 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003787
Arun Menon906de572013-06-18 17:01:40 -07003788 if (i >= drv_ctx.op_buf.actualcount) {
3789 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
3790 eRet = OMX_ErrorInsufficientResources;
3791 }
3792
3793 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003794#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003795 if (m_enable_android_native_buffers) {
3796 if (m_use_android_native_buffers) {
3797 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
3798 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3799 handle = (private_handle_t *)nBuf->handle;
3800 privateAppData = params->pAppPrivate;
3801 } else {
3802 handle = (private_handle_t *)buff;
3803 privateAppData = appData;
3804 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003805
Arun Menon906de572013-06-18 17:01:40 -07003806 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
3807 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
3808 " expected %u, got %lu",
3809 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
3810 return OMX_ErrorBadParameter;
3811 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003812
Arun Menon906de572013-06-18 17:01:40 -07003813 if (!m_use_android_native_buffers) {
3814 if (!secure_mode) {
3815 buff = (OMX_U8*)mmap(0, handle->size,
3816 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3817 if (buff == MAP_FAILED) {
3818 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3819 return OMX_ErrorInsufficientResources;
3820 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003821 }
3822 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003823#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003824 native_buffer[i].nativehandle = handle;
3825 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003826#endif
Arun Menon906de572013-06-18 17:01:40 -07003827 if (!handle) {
3828 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
3829 return OMX_ErrorBadParameter;
3830 }
3831 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
3832 drv_ctx.ptr_outputbuffer[i].offset = 0;
3833 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
3834 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
3835 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
3836 } else
3837#endif
3838
3839 if (!ouput_egl_buffers && !m_use_output_pmem) {
3840#ifdef USE_ION
3841 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
3842 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
3843 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
3844 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
3845 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
3846 DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd);
3847 return OMX_ErrorInsufficientResources;
3848 }
3849 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3850 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
3851#else
3852 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3853 open (MEM_DEVICE,O_RDWR);
3854
3855 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
3856 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
3857 return OMX_ErrorInsufficientResources;
3858 }
3859
3860 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
3861 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
3862 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3863 open (MEM_DEVICE,O_RDWR);
3864 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
3865 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
3866 return OMX_ErrorInsufficientResources;
3867 }
3868 }
3869
3870 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
3871 drv_ctx.op_buf.buffer_size,
3872 drv_ctx.op_buf.alignment)) {
3873 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
3874 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
3875 return OMX_ErrorInsufficientResources;
3876 }
3877#endif
3878 if (!secure_mode) {
3879 drv_ctx.ptr_outputbuffer[i].bufferaddr =
3880 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
3881 PROT_READ|PROT_WRITE, MAP_SHARED,
3882 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
3883 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
3884 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
3885#ifdef USE_ION
3886 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
3887#endif
3888 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
3889 return OMX_ErrorInsufficientResources;
3890 }
3891 }
3892 drv_ctx.ptr_outputbuffer[i].offset = 0;
3893 privateAppData = appData;
3894 } else {
3895
3896 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
3897 if (!appData || !bytes ) {
3898 if (!secure_mode && !buffer) {
3899 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
3900 return OMX_ErrorBadParameter;
3901 }
3902 }
3903
3904 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
3905 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
3906 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
3907 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
3908 !pmem_list->nEntries ||
3909 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3910 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
3911 return OMX_ErrorBadParameter;
3912 }
3913 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
3914 pmem_list->entryList->entry;
3915 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
3916 pmem_info->pmem_fd);
3917 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
3918 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
3919 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
3920 drv_ctx.ptr_outputbuffer[i].mmaped_size =
3921 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
3922 privateAppData = appData;
3923 }
3924 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
3925 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
3926
3927 *bufferHdr = (m_out_mem_ptr + i );
3928 if (secure_mode)
3929 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
3930 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
3931 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
3932 sizeof (vdec_bufferpayload));
3933
3934 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
3935 drv_ctx.ptr_outputbuffer[i].bufferaddr,
3936 drv_ctx.ptr_outputbuffer[i].pmem_fd );
3937
3938 buf.index = i;
3939 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3940 buf.memory = V4L2_MEMORY_USERPTR;
3941 plane[0].length = drv_ctx.op_buf.buffer_size;
3942 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
3943 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
3944 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
3945 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
3946 plane[0].data_offset = 0;
3947 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
3948 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
3949 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
3950 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
3951#ifdef USE_ION
3952 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
3953#endif
3954 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
3955 plane[extra_idx].data_offset = 0;
3956 } else if (extra_idx >= VIDEO_MAX_PLANES) {
3957 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003958 return OMX_ErrorBadParameter;
3959 }
Arun Menon906de572013-06-18 17:01:40 -07003960 buf.m.planes = plane;
3961 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003962
Arun Menon906de572013-06-18 17:01:40 -07003963 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
3964 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
3965 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003966 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003967 }
3968
Arun Menon906de572013-06-18 17:01:40 -07003969 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
3970 enum v4l2_buf_type buf_type;
3971 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3972 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
3973 return OMX_ErrorInsufficientResources;
3974 } else {
3975 streaming[CAPTURE_PORT] = true;
3976 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003977 }
3978 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003979
Arun Menon906de572013-06-18 17:01:40 -07003980 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
3981 if (m_enable_android_native_buffers) {
3982 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
3983 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
3984 } else {
3985 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003986 }
Arun Menon906de572013-06-18 17:01:40 -07003987 (*bufferHdr)->pAppPrivate = privateAppData;
3988 BITMASK_SET(&m_out_bm_count,i);
3989 }
3990 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003991}
3992
3993/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003994 FUNCTION
3995 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07003996
Arun Menon906de572013-06-18 17:01:40 -07003997 DESCRIPTION
3998 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003999
Arun Menon906de572013-06-18 17:01:40 -07004000 PARAMETERS
4001 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004002
Arun Menon906de572013-06-18 17:01:40 -07004003 RETURN VALUE
4004 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004005
Arun Menon906de572013-06-18 17:01:40 -07004006 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004007OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004008 OMX_IN OMX_HANDLETYPE hComp,
4009 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4010 OMX_IN OMX_U32 port,
4011 OMX_IN OMX_PTR appData,
4012 OMX_IN OMX_U32 bytes,
4013 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004014{
Arun Menon906de572013-06-18 17:01:40 -07004015 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4016 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4017 if (!m_inp_heap_ptr)
4018 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4019 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4020 drv_ctx.ip_buf.actualcount);
4021 if (!m_phdr_pmem_ptr)
4022 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4023 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4024 drv_ctx.ip_buf.actualcount);
4025 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4026 DEBUG_PRINT_ERROR("Insufficent memory");
4027 eRet = OMX_ErrorInsufficientResources;
4028 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4029 input_use_buffer = true;
4030 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4031 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4032 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4033 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4034 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4035 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4036 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4037 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4038 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
4039 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4040 (unsigned)NULL, (unsigned)NULL)) {
4041 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4042 return OMX_ErrorInsufficientResources;
4043 }
4044 m_in_alloc_cnt++;
4045 } else {
4046 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4047 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004048 }
Arun Menon906de572013-06-18 17:01:40 -07004049 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004050}
4051
4052/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004053 FUNCTION
4054 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004055
Arun Menon906de572013-06-18 17:01:40 -07004056 DESCRIPTION
4057 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004058
Arun Menon906de572013-06-18 17:01:40 -07004059 PARAMETERS
4060 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004061
Arun Menon906de572013-06-18 17:01:40 -07004062 RETURN VALUE
4063 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004064
Arun Menon906de572013-06-18 17:01:40 -07004065 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004066OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004067 OMX_IN OMX_HANDLETYPE hComp,
4068 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4069 OMX_IN OMX_U32 port,
4070 OMX_IN OMX_PTR appData,
4071 OMX_IN OMX_U32 bytes,
4072 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004073{
Arun Menon906de572013-06-18 17:01:40 -07004074 OMX_ERRORTYPE error = OMX_ErrorNone;
4075 struct vdec_setbuffer_cmd setbuffers;
4076
4077 if (bufferHdr == NULL || bytes == 0) {
4078 if (!secure_mode && buffer == NULL) {
4079 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4080 return OMX_ErrorBadParameter;
4081 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004082 }
Arun Menon906de572013-06-18 17:01:40 -07004083 if (m_state == OMX_StateInvalid) {
4084 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4085 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004086 }
Arun Menon906de572013-06-18 17:01:40 -07004087 if (port == OMX_CORE_INPUT_PORT_INDEX)
4088 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4089 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4090 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4091 else {
4092 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4093 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004094 }
Arun Menon906de572013-06-18 17:01:40 -07004095 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4096 if (error == OMX_ErrorNone) {
4097 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4098 // Send the callback now
4099 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4100 post_event(OMX_CommandStateSet,OMX_StateIdle,
4101 OMX_COMPONENT_GENERATE_EVENT);
4102 }
4103 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4104 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4105 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4106 post_event(OMX_CommandPortEnable,
4107 OMX_CORE_INPUT_PORT_INDEX,
4108 OMX_COMPONENT_GENERATE_EVENT);
4109 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4110 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4111 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4112 post_event(OMX_CommandPortEnable,
4113 OMX_CORE_OUTPUT_PORT_INDEX,
4114 OMX_COMPONENT_GENERATE_EVENT);
4115 }
4116 }
4117 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004118}
4119
4120OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004121 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004122{
Arun Menon906de572013-06-18 17:01:40 -07004123 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4124 if (m_inp_heap_ptr[bufferindex].pBuffer)
4125 free(m_inp_heap_ptr[bufferindex].pBuffer);
4126 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4127 }
4128 if (pmem_bufferHdr)
4129 free_input_buffer(pmem_bufferHdr);
4130 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004131}
4132
4133OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4134{
Arun Menon906de572013-06-18 17:01:40 -07004135 unsigned int index = 0;
4136 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4137 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004138 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004139
Arun Menon906de572013-06-18 17:01:40 -07004140 index = bufferHdr - m_inp_mem_ptr;
4141 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4142
4143 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
4144 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4145 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4146 struct vdec_setbuffer_cmd setbuffers;
4147 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4148 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4149 sizeof (vdec_bufferpayload));
4150 if (!secure_mode) {
4151 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4152 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4153 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4154 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4155 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4156 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4157 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4158 }
4159 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4160 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4161 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4162 free(m_desc_buffer_ptr[index].buf_addr);
4163 m_desc_buffer_ptr[index].buf_addr = NULL;
4164 m_desc_buffer_ptr[index].desc_data_size = 0;
4165 }
4166#ifdef USE_ION
4167 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4168#endif
4169 }
4170 }
4171
4172 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004173}
4174
4175OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4176{
Arun Menon906de572013-06-18 17:01:40 -07004177 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004178
Arun Menon906de572013-06-18 17:01:40 -07004179 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4180 return OMX_ErrorBadParameter;
4181 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004182
Arun Menon906de572013-06-18 17:01:40 -07004183 index = bufferHdr - m_out_mem_ptr;
4184 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004185
Arun Menon906de572013-06-18 17:01:40 -07004186 if (index < drv_ctx.op_buf.actualcount
4187 && drv_ctx.ptr_outputbuffer) {
4188 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
4189 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004190
Arun Menon906de572013-06-18 17:01:40 -07004191 struct vdec_setbuffer_cmd setbuffers;
4192 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4193 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4194 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004195#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004196 if (m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004197 if (!secure_mode) {
Arun Menon906de572013-06-18 17:01:40 -07004198 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4199 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4200 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4201 }
Praveen Chavan212671f2013-04-05 20:00:42 -07004202 }
Arun Menon906de572013-06-18 17:01:40 -07004203 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4204 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004205#endif
Arun Menon906de572013-06-18 17:01:40 -07004206 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4207 if (!secure_mode) {
4208 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4209 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4210 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4211 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4212 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4213 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4214 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4215 }
4216 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4217 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004218#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004219 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004220#endif
Arun Menon906de572013-06-18 17:01:40 -07004221 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004222#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004223 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004224#endif
Arun Menon906de572013-06-18 17:01:40 -07004225 if (release_output_done()) {
4226 free_extradata();
4227 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004228 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004229
Arun Menon906de572013-06-18 17:01:40 -07004230 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004231
4232}
4233
4234OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004235 OMX_BUFFERHEADERTYPE **bufferHdr,
4236 OMX_U32 port,
4237 OMX_PTR appData,
4238 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004239{
Arun Menon906de572013-06-18 17:01:40 -07004240 OMX_BUFFERHEADERTYPE *input = NULL;
4241 unsigned char *buf_addr = NULL;
4242 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4243 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004244
Arun Menon906de572013-06-18 17:01:40 -07004245 /* Sanity Check*/
4246 if (bufferHdr == NULL) {
4247 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004248 }
4249
Arun Menon906de572013-06-18 17:01:40 -07004250 if (m_inp_heap_ptr == NULL) {
Leena Winterrowd3e959242013-08-12 18:26:57 -07004251 m_frame_parser.reset();
Arun Menon906de572013-06-18 17:01:40 -07004252 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4253 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4254 drv_ctx.ip_buf.actualcount);
4255 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4256 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4257 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004258
Arun Menon906de572013-06-18 17:01:40 -07004259 if (m_inp_heap_ptr == NULL) {
4260 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4261 return OMX_ErrorInsufficientResources;
4262 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004263 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004264
Arun Menon906de572013-06-18 17:01:40 -07004265 /*Find a Free index*/
4266 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4267 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
4268 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4269 break;
4270 }
4271 }
4272
4273 if (i < drv_ctx.ip_buf.actualcount) {
4274 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4275
4276 if (buf_addr == NULL) {
4277 return OMX_ErrorInsufficientResources;
4278 }
4279
4280 *bufferHdr = (m_inp_heap_ptr + i);
4281 input = *bufferHdr;
4282 BITMASK_SET(&m_heap_inp_bm_count,i);
4283
4284 input->pBuffer = (OMX_U8 *)buf_addr;
4285 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4286 input->nVersion.nVersion = OMX_SPEC_VERSION;
4287 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4288 input->pAppPrivate = appData;
4289 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4290 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4291 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4292 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
4293 /*Add the Buffers to freeq*/
4294 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4295 (unsigned)NULL, (unsigned)NULL)) {
4296 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4297 return OMX_ErrorInsufficientResources;
4298 }
4299 } else {
4300 return OMX_ErrorBadParameter;
4301 }
4302
4303 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004304
4305}
4306
4307
4308/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004309 FUNCTION
4310 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004311
Arun Menon906de572013-06-18 17:01:40 -07004312 DESCRIPTION
4313 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004314
Arun Menon906de572013-06-18 17:01:40 -07004315 PARAMETERS
4316 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004317
Arun Menon906de572013-06-18 17:01:40 -07004318 RETURN VALUE
4319 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004320
Arun Menon906de572013-06-18 17:01:40 -07004321 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004322OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004323 OMX_IN OMX_HANDLETYPE hComp,
4324 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4325 OMX_IN OMX_U32 port,
4326 OMX_IN OMX_PTR appData,
4327 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004328{
4329
Arun Menon906de572013-06-18 17:01:40 -07004330 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4331 struct vdec_setbuffer_cmd setbuffers;
4332 OMX_BUFFERHEADERTYPE *input = NULL;
4333 unsigned i = 0;
4334 unsigned char *buf_addr = NULL;
4335 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004336
Arun Menon906de572013-06-18 17:01:40 -07004337 if (bytes != drv_ctx.ip_buf.buffer_size) {
4338 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
4339 bytes, drv_ctx.ip_buf.buffer_size);
4340 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004341 }
4342
Arun Menon906de572013-06-18 17:01:40 -07004343 if (!m_inp_mem_ptr) {
4344 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4345 drv_ctx.ip_buf.actualcount,
4346 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004347
Arun Menon906de572013-06-18 17:01:40 -07004348 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4349 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4350
4351 if (m_inp_mem_ptr == NULL) {
4352 return OMX_ErrorInsufficientResources;
4353 }
4354
4355 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4356 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4357
4358 if (drv_ctx.ptr_inputbuffer == NULL) {
4359 return OMX_ErrorInsufficientResources;
4360 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004361#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004362 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4363 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004364
Arun Menon906de572013-06-18 17:01:40 -07004365 if (drv_ctx.ip_buf_ion_info == NULL) {
4366 return OMX_ErrorInsufficientResources;
4367 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004368#endif
4369
Arun Menon906de572013-06-18 17:01:40 -07004370 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4371 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004372#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004373 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004374#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004375 }
4376 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004377
Arun Menon906de572013-06-18 17:01:40 -07004378 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4379 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4380 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4381 break;
4382 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004383 }
Arun Menon906de572013-06-18 17:01:40 -07004384
4385 if (i < drv_ctx.ip_buf.actualcount) {
4386 struct v4l2_buffer buf;
4387 struct v4l2_plane plane;
4388 int rc;
4389 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4390#ifdef USE_ION
4391 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4392 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4393 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4394 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4395 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4396 return OMX_ErrorInsufficientResources;
4397 }
4398 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4399#else
4400 pmem_fd = open (MEM_DEVICE,O_RDWR);
4401
4402 if (pmem_fd < 0) {
4403 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4404 return OMX_ErrorInsufficientResources;
4405 }
4406
4407 if (pmem_fd == 0) {
4408 pmem_fd = open (MEM_DEVICE,O_RDWR);
4409
4410 if (pmem_fd < 0) {
4411 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4412 return OMX_ErrorInsufficientResources;
4413 }
4414 }
4415
4416 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4417 drv_ctx.ip_buf.alignment)) {
4418 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4419 close(pmem_fd);
4420 return OMX_ErrorInsufficientResources;
4421 }
4422#endif
4423 if (!secure_mode) {
4424 buf_addr = (unsigned char *)mmap(NULL,
4425 drv_ctx.ip_buf.buffer_size,
4426 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4427
4428 if (buf_addr == MAP_FAILED) {
4429 close(pmem_fd);
4430#ifdef USE_ION
4431 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4432#endif
4433 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4434 return OMX_ErrorInsufficientResources;
4435 }
4436 }
4437 *bufferHdr = (m_inp_mem_ptr + i);
4438 if (secure_mode)
4439 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4440 else
4441 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4442 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4443 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4444 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4445 drv_ctx.ptr_inputbuffer [i].offset = 0;
4446
4447
4448 buf.index = i;
4449 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4450 buf.memory = V4L2_MEMORY_USERPTR;
4451 plane.bytesused = 0;
4452 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4453 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4454 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4455 plane.reserved[1] = 0;
4456 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4457 buf.m.planes = &plane;
4458 buf.length = 1;
4459
4460 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4461 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4462
4463 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4464
4465 if (rc) {
4466 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4467 /*TODO: How to handle this case */
4468 return OMX_ErrorInsufficientResources;
4469 }
4470
4471 input = *bufferHdr;
4472 BITMASK_SET(&m_inp_bm_count,i);
4473 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4474 if (secure_mode)
4475 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4476 else
4477 input->pBuffer = (OMX_U8 *)buf_addr;
4478 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4479 input->nVersion.nVersion = OMX_SPEC_VERSION;
4480 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4481 input->pAppPrivate = appData;
4482 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4483 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4484
4485 if (drv_ctx.disable_dmx) {
4486 eRet = allocate_desc_buffer(i);
4487 }
4488 } else {
4489 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4490 eRet = OMX_ErrorInsufficientResources;
4491 }
4492 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004493}
4494
4495
4496/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004497 FUNCTION
4498 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004499
Arun Menon906de572013-06-18 17:01:40 -07004500 DESCRIPTION
4501 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004502
Arun Menon906de572013-06-18 17:01:40 -07004503 PARAMETERS
4504 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004505
Arun Menon906de572013-06-18 17:01:40 -07004506 RETURN VALUE
4507 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004508
Arun Menon906de572013-06-18 17:01:40 -07004509 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004510OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004511 OMX_IN OMX_HANDLETYPE hComp,
4512 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4513 OMX_IN OMX_U32 port,
4514 OMX_IN OMX_PTR appData,
4515 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004516{
Arun Menon906de572013-06-18 17:01:40 -07004517 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4518 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4519 unsigned i= 0; // Temporary counter
4520 struct vdec_setbuffer_cmd setbuffers;
4521 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004522#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004523 int ion_device_fd =-1;
4524 struct ion_allocation_data ion_alloc_data;
4525 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004526#endif
Arun Menon906de572013-06-18 17:01:40 -07004527 if (!m_out_mem_ptr) {
4528 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4529 drv_ctx.op_buf.actualcount,
4530 drv_ctx.op_buf.buffer_size);
4531 int nBufHdrSize = 0;
4532 int nPlatformEntrySize = 0;
4533 int nPlatformListSize = 0;
4534 int nPMEMInfoSize = 0;
4535 int pmem_fd = -1;
4536 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004537
Arun Menon906de572013-06-18 17:01:40 -07004538 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4539 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4540 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004541
Arun Menon906de572013-06-18 17:01:40 -07004542 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4543 drv_ctx.op_buf.actualcount);
4544 nBufHdrSize = drv_ctx.op_buf.actualcount *
4545 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004546
Arun Menon906de572013-06-18 17:01:40 -07004547 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4548 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4549 nPlatformListSize = drv_ctx.op_buf.actualcount *
4550 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4551 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4552 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004553
Arun Menon906de572013-06-18 17:01:40 -07004554 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4555 sizeof(OMX_BUFFERHEADERTYPE),
4556 nPMEMInfoSize,
4557 nPlatformListSize);
4558 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4559 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004560#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004561 ion_device_fd = alloc_map_ion_memory(
4562 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4563 drv_ctx.op_buf.alignment,
4564 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4565 if (ion_device_fd < 0) {
4566 return OMX_ErrorInsufficientResources;
4567 }
4568 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004569#else
Arun Menon906de572013-06-18 17:01:40 -07004570 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004571
Arun Menon906de572013-06-18 17:01:40 -07004572 if (pmem_fd < 0) {
4573 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4574 drv_ctx.op_buf.buffer_size);
4575 return OMX_ErrorInsufficientResources;
4576 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004577
Arun Menon906de572013-06-18 17:01:40 -07004578 if (pmem_fd == 0) {
4579 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004580
Arun Menon906de572013-06-18 17:01:40 -07004581 if (pmem_fd < 0) {
4582 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4583 drv_ctx.op_buf.buffer_size);
4584 return OMX_ErrorInsufficientResources;
4585 }
4586 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004587
Arun Menon906de572013-06-18 17:01:40 -07004588 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4589 drv_ctx.op_buf.actualcount,
4590 drv_ctx.op_buf.alignment)) {
4591 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4592 close(pmem_fd);
4593 return OMX_ErrorInsufficientResources;
4594 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004595#endif
Arun Menon906de572013-06-18 17:01:40 -07004596 if (!secure_mode) {
4597 pmem_baseaddress = (unsigned char *)mmap(NULL,
4598 (drv_ctx.op_buf.buffer_size *
4599 drv_ctx.op_buf.actualcount),
4600 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4601 if (pmem_baseaddress == MAP_FAILED) {
4602 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4603 drv_ctx.op_buf.buffer_size);
4604 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004605#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004606 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004607#endif
Arun Menon906de572013-06-18 17:01:40 -07004608 return OMX_ErrorInsufficientResources;
4609 }
4610 }
4611 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4612 // Alloc mem for platform specific info
4613 char *pPtr=NULL;
4614 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4615 nPMEMInfoSize,1);
4616 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4617 calloc (sizeof(struct vdec_bufferpayload),
4618 drv_ctx.op_buf.actualcount);
4619 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4620 calloc (sizeof (struct vdec_output_frameinfo),
4621 drv_ctx.op_buf.actualcount);
4622#ifdef USE_ION
4623 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4624 calloc (sizeof(struct vdec_ion),
4625 drv_ctx.op_buf.actualcount);
4626#endif
4627
4628 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4629 && drv_ctx.ptr_respbuffer) {
4630 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4631 (drv_ctx.op_buf.buffer_size *
4632 drv_ctx.op_buf.actualcount);
4633 bufHdr = m_out_mem_ptr;
4634 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4635 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4636 (((char *) m_platform_list) + nPlatformListSize);
4637 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4638 (((char *) m_platform_entry) + nPlatformEntrySize);
4639 pPlatformList = m_platform_list;
4640 pPlatformEntry = m_platform_entry;
4641 pPMEMInfo = m_pmem_info;
4642
4643 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
4644
4645 // Settting the entire storage nicely
4646 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
4647 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
4648 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4649 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4650 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4651 // Set the values when we determine the right HxW param
4652 bufHdr->nAllocLen = bytes;
4653 bufHdr->nFilledLen = 0;
4654 bufHdr->pAppPrivate = appData;
4655 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4656 // Platform specific PMEM Information
4657 // Initialize the Platform Entry
4658 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
4659 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4660 pPlatformEntry->entry = pPMEMInfo;
4661 // Initialize the Platform List
4662 pPlatformList->nEntries = 1;
4663 pPlatformList->entryList = pPlatformEntry;
4664 // Keep pBuffer NULL till vdec is opened
4665 bufHdr->pBuffer = NULL;
4666 bufHdr->nOffset = 0;
4667
4668 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4669 pPMEMInfo->pmem_fd = 0;
4670 bufHdr->pPlatformPrivate = pPlatformList;
4671
4672 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
4673 m_pmem_info[i].pmem_fd = pmem_fd;
4674#ifdef USE_ION
4675 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
4676 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
4677 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
4678#endif
4679
4680 /*Create a mapping between buffers*/
4681 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
4682 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
4683 &drv_ctx.ptr_outputbuffer[i];
4684 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
4685 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4686 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
4687
4688 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
4689 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
4690 drv_ctx.ptr_outputbuffer[i].bufferaddr);
4691 // Move the buffer and buffer header pointers
4692 bufHdr++;
4693 pPMEMInfo++;
4694 pPlatformEntry++;
4695 pPlatformList++;
4696 }
4697 } else {
4698 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
4699 m_out_mem_ptr, pPtr);
4700 if (m_out_mem_ptr) {
4701 free(m_out_mem_ptr);
4702 m_out_mem_ptr = NULL;
4703 }
4704 if (pPtr) {
4705 free(pPtr);
4706 pPtr = NULL;
4707 }
4708 if (drv_ctx.ptr_outputbuffer) {
4709 free(drv_ctx.ptr_outputbuffer);
4710 drv_ctx.ptr_outputbuffer = NULL;
4711 }
4712 if (drv_ctx.ptr_respbuffer) {
4713 free(drv_ctx.ptr_respbuffer);
4714 drv_ctx.ptr_respbuffer = NULL;
4715 }
4716#ifdef USE_ION
4717 if (drv_ctx.op_buf_ion_info) {
4718 DEBUG_PRINT_LOW("\n Free o/p ion context");
4719 free(drv_ctx.op_buf_ion_info);
4720 drv_ctx.op_buf_ion_info = NULL;
4721 }
4722#endif
4723 eRet = OMX_ErrorInsufficientResources;
4724 }
4725 if (eRet == OMX_ErrorNone)
4726 eRet = allocate_extradata();
4727 }
4728
4729 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4730 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4731 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
4732 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004733 }
4734 }
Arun Menon906de572013-06-18 17:01:40 -07004735
4736 if (eRet == OMX_ErrorNone) {
4737 if (i < drv_ctx.op_buf.actualcount) {
4738 struct v4l2_buffer buf;
4739 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4740 int rc;
4741 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4742
4743 drv_ctx.ptr_outputbuffer[i].buffer_len =
4744 drv_ctx.op_buf.buffer_size;
4745
4746 *bufferHdr = (m_out_mem_ptr + i );
4747 if (secure_mode) {
4748 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4749 }
4750 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
4751
4752 buf.index = i;
4753 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4754 buf.memory = V4L2_MEMORY_USERPTR;
4755 plane[0].length = drv_ctx.op_buf.buffer_size;
4756 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4757 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004758#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004759 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004760#endif
Arun Menon906de572013-06-18 17:01:40 -07004761 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4762 plane[0].data_offset = 0;
4763 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4764 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4765 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4766 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 -07004767#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004768 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004769#endif
Arun Menon906de572013-06-18 17:01:40 -07004770 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4771 plane[extra_idx].data_offset = 0;
4772 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4773 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
4774 return OMX_ErrorBadParameter;
4775 }
4776 buf.m.planes = plane;
4777 buf.length = drv_ctx.num_planes;
4778 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
4779 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4780 if (rc) {
4781 /*TODO: How to handle this case */
4782 return OMX_ErrorInsufficientResources;
4783 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004784
Arun Menon906de572013-06-18 17:01:40 -07004785 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
4786 enum v4l2_buf_type buf_type;
4787 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4788 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
4789 if (rc) {
4790 return OMX_ErrorInsufficientResources;
4791 } else {
4792 streaming[CAPTURE_PORT] = true;
4793 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4794 }
4795 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004796
Arun Menon906de572013-06-18 17:01:40 -07004797 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
4798 (*bufferHdr)->pAppPrivate = appData;
4799 BITMASK_SET(&m_out_bm_count,i);
4800 } else {
4801 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
4802 eRet = OMX_ErrorInsufficientResources;
4803 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004804 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004805
Arun Menon906de572013-06-18 17:01:40 -07004806 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004807}
4808
4809
4810// AllocateBuffer -- API Call
4811/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004812 FUNCTION
4813 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004814
Arun Menon906de572013-06-18 17:01:40 -07004815 DESCRIPTION
4816 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07004817
Arun Menon906de572013-06-18 17:01:40 -07004818 PARAMETERS
4819 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004820
Arun Menon906de572013-06-18 17:01:40 -07004821 RETURN VALUE
4822 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004823
Arun Menon906de572013-06-18 17:01:40 -07004824 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004825OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004826 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4827 OMX_IN OMX_U32 port,
4828 OMX_IN OMX_PTR appData,
4829 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004830{
4831 unsigned i = 0;
4832 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
4833
4834 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07004835 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004836 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
4837 return OMX_ErrorInvalidState;
4838 }
4839
Arun Menon906de572013-06-18 17:01:40 -07004840 if (port == OMX_CORE_INPUT_PORT_INDEX) {
4841 if (arbitrary_bytes) {
4842 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
4843 } else {
4844 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
4845 }
4846 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08004847 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
4848 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07004849 } else {
4850 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4851 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004852 }
4853 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07004854 if (eRet == OMX_ErrorNone) {
4855 if (allocate_done()) {
4856 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004857 // Send the callback now
4858 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4859 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07004860 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004861 }
4862 }
Arun Menon906de572013-06-18 17:01:40 -07004863 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
4864 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4865 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4866 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004867 OMX_CORE_INPUT_PORT_INDEX,
4868 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07004869 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004870 }
Arun Menon906de572013-06-18 17:01:40 -07004871 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
4872 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4873 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004874 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07004875 OMX_CORE_OUTPUT_PORT_INDEX,
4876 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004877 }
4878 }
4879 }
4880 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
4881 return eRet;
4882}
4883
4884// Free Buffer - API call
4885/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004886 FUNCTION
4887 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004888
Arun Menon906de572013-06-18 17:01:40 -07004889 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07004890
Arun Menon906de572013-06-18 17:01:40 -07004891 PARAMETERS
4892 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004893
Arun Menon906de572013-06-18 17:01:40 -07004894 RETURN VALUE
4895 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004896
Arun Menon906de572013-06-18 17:01:40 -07004897 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004898OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004899 OMX_IN OMX_U32 port,
4900 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004901{
4902 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4903 unsigned int nPortIndex;
4904 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
4905
Arun Menon906de572013-06-18 17:01:40 -07004906 if (m_state == OMX_StateIdle &&
4907 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004908 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
Arun Menon906de572013-06-18 17:01:40 -07004909 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
4910 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07004911 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Arun Menon906de572013-06-18 17:01:40 -07004912 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
4913 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
4914 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
4915 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Arun Menon9f098152013-05-08 13:53:54 -07004916 DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port);
Arun Menon906de572013-06-18 17:01:40 -07004917 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004918 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
4919 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07004920 OMX_ErrorPortUnpopulated,
4921 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004922
4923 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07004924 } else if (m_state != OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004925 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
4926 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07004927 OMX_ErrorPortUnpopulated,
4928 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004929 }
4930
Arun Menon906de572013-06-18 17:01:40 -07004931 if (port == OMX_CORE_INPUT_PORT_INDEX) {
4932 /*Check if arbitrary bytes*/
4933 if (!arbitrary_bytes && !input_use_buffer)
4934 nPortIndex = buffer - m_inp_mem_ptr;
4935 else
4936 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004937
4938 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07004939 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
4940 // Clear the bit associated with it.
4941 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
4942 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
4943 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004944
Arun Menon906de572013-06-18 17:01:40 -07004945 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
4946 if (m_phdr_pmem_ptr)
4947 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
4948 } else {
4949 if (arbitrary_bytes) {
4950 if (m_phdr_pmem_ptr)
4951 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
4952 else
4953 free_input_buffer(nPortIndex,NULL);
4954 } else
4955 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004956 }
Arun Menon906de572013-06-18 17:01:40 -07004957 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05304958 if(release_input_done())
4959 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07004960 /*Free the Buffer Header*/
4961 if (release_input_done()) {
4962 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
4963 free_input_buffer_header();
4964 }
4965 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004966 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
4967 eRet = OMX_ErrorBadPortIndex;
4968 }
4969
Arun Menon906de572013-06-18 17:01:40 -07004970 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
4971 && release_input_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004972 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
4973 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
4974 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07004975 OMX_CORE_INPUT_PORT_INDEX,
4976 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004977 }
Arun Menon906de572013-06-18 17:01:40 -07004978 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004979 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08004980 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07004981 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004982 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
4983 // Clear the bit associated with it.
4984 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
4985 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08004986 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004987
Surajit Podder12aefac2013-08-06 18:43:32 +05304988 if(release_output_done()) {
4989 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
4990 }
Arun Menon906de572013-06-18 17:01:40 -07004991 if (release_output_done()) {
4992 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004993 }
Arun Menon906de572013-06-18 17:01:40 -07004994 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004995 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
4996 eRet = OMX_ErrorBadPortIndex;
4997 }
Arun Menon906de572013-06-18 17:01:40 -07004998 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
4999 && release_output_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005000 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5001
Arun Menon906de572013-06-18 17:01:40 -07005002 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5003 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005004#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005005 if (m_enable_android_native_buffers) {
5006 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5007 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5008 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005009#endif
5010
Arun Menon906de572013-06-18 17:01:40 -07005011 post_event(OMX_CommandPortDisable,
5012 OMX_CORE_OUTPUT_PORT_INDEX,
5013 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005014 }
Arun Menon906de572013-06-18 17:01:40 -07005015 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005016 eRet = OMX_ErrorBadPortIndex;
5017 }
Arun Menon906de572013-06-18 17:01:40 -07005018 if ((eRet == OMX_ErrorNone) &&
5019 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5020 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005021 // Send the callback now
5022 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5023 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005024 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005025 }
5026 }
5027 return eRet;
5028}
5029
5030
5031/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005032 FUNCTION
5033 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005034
Arun Menon906de572013-06-18 17:01:40 -07005035 DESCRIPTION
5036 This routine is used to push the encoded video frames to
5037 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005038
Arun Menon906de572013-06-18 17:01:40 -07005039 PARAMETERS
5040 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005041
Arun Menon906de572013-06-18 17:01:40 -07005042 RETURN VALUE
5043 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005044
Arun Menon906de572013-06-18 17:01:40 -07005045 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005046OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005047 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005048{
Arun Menon906de572013-06-18 17:01:40 -07005049 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5050 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005051
Arun Menon906de572013-06-18 17:01:40 -07005052 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5053 codec_config_flag = true;
5054 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5055 } else {
5056 codec_config_flag = false;
5057 }
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07005058
Arun Menon906de572013-06-18 17:01:40 -07005059 if (m_state == OMX_StateInvalid) {
5060 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5061 return OMX_ErrorInvalidState;
5062 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005063
Arun Menon906de572013-06-18 17:01:40 -07005064 if (buffer == NULL) {
5065 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5066 return OMX_ErrorBadParameter;
5067 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005068
Arun Menon906de572013-06-18 17:01:40 -07005069 if (!m_inp_bEnabled) {
5070 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5071 return OMX_ErrorIncorrectStateOperation;
5072 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005073
Arun Menon906de572013-06-18 17:01:40 -07005074 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
5075 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
5076 return OMX_ErrorBadPortIndex;
5077 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005078
5079#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005080 if (iDivXDrmDecrypt) {
5081 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5082 if (drmErr != OMX_ErrorNone) {
5083 // this error can be ignored
5084 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5085 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005086 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005087#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005088 if (perf_flag) {
5089 if (!latency) {
5090 dec_time.stop();
5091 latency = dec_time.processing_time_us();
5092 dec_time.start();
5093 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005094 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005095
Arun Menon906de572013-06-18 17:01:40 -07005096 if (arbitrary_bytes) {
5097 nBufferIndex = buffer - m_inp_heap_ptr;
5098 } else {
5099 if (input_use_buffer == true) {
5100 nBufferIndex = buffer - m_inp_heap_ptr;
5101 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5102 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5103 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5104 buffer = &m_inp_mem_ptr[nBufferIndex];
5105 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5106 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5107 } else {
5108 nBufferIndex = buffer - m_inp_mem_ptr;
5109 }
5110 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005111
Arun Menon906de572013-06-18 17:01:40 -07005112 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
5113 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5114 return OMX_ErrorBadParameter;
5115 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005116
Arun Menon906de572013-06-18 17:01:40 -07005117 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5118 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5119 if (arbitrary_bytes) {
5120 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005121 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005122 } else {
5123 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5124 set_frame_rate(buffer->nTimeStamp);
5125 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5126 }
5127 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005128}
5129
5130/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005131 FUNCTION
5132 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005133
Arun Menon906de572013-06-18 17:01:40 -07005134 DESCRIPTION
5135 This routine is used to push the encoded video frames to
5136 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005137
Arun Menon906de572013-06-18 17:01:40 -07005138 PARAMETERS
5139 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005140
Arun Menon906de572013-06-18 17:01:40 -07005141 RETURN VALUE
5142 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005143
Arun Menon906de572013-06-18 17:01:40 -07005144 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005145OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005146 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005147{
Arun Menon906de572013-06-18 17:01:40 -07005148 int push_cnt = 0,i=0;
5149 unsigned nPortIndex = 0;
5150 OMX_ERRORTYPE ret = OMX_ErrorNone;
5151 struct vdec_input_frameinfo frameinfo;
5152 struct vdec_bufferpayload *temp_buffer;
5153 struct vdec_seqheader seq_header;
5154 bool port_setting_changed = true;
5155 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005156
Arun Menon906de572013-06-18 17:01:40 -07005157 /*Should we generate a Aync error event*/
5158 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
5159 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5160 return OMX_ErrorBadParameter;
5161 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005162
Arun Menon906de572013-06-18 17:01:40 -07005163 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005164
Arun Menon906de572013-06-18 17:01:40 -07005165 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
5166 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5167 nPortIndex);
5168 return OMX_ErrorBadParameter;
5169 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005170
Arun Menon906de572013-06-18 17:01:40 -07005171 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005172
Arun Menon906de572013-06-18 17:01:40 -07005173 /* return zero length and not an EOS buffer */
5174 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5175 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
5176 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5177 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5178 OMX_COMPONENT_GENERATE_EBD);
5179 return OMX_ErrorNone;
5180 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005181
5182
Arun Menon906de572013-06-18 17:01:40 -07005183 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5184 mp4StreamType psBits;
5185 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5186 psBits.numBytes = buffer->nFilledLen;
5187 mp4_headerparser.parseHeader(&psBits);
5188 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5189 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5190 if (not_coded_vop) {
5191 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
5192 buffer->nFilledLen,frame_count);
5193 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
5194 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5195 not_coded_vop = false;
5196 buffer->nFilledLen = 0;
5197 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005198 }
5199 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005200
Arun Menon906de572013-06-18 17:01:40 -07005201 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005202
Arun Menon906de572013-06-18 17:01:40 -07005203 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005204
Arun Menon906de572013-06-18 17:01:40 -07005205 ) {
5206 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5207 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5208 OMX_COMPONENT_GENERATE_EBD);
5209 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005210 }
5211
Arun Menon906de572013-06-18 17:01:40 -07005212 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005213
Arun Menon906de572013-06-18 17:01:40 -07005214 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) {
5215 return OMX_ErrorBadParameter;
5216 }
5217 /* If its first frame, H264 codec and reject is true, then parse the nal
5218 and get the profile. Based on this, reject the clip playback */
5219 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5220 m_reject_avc_1080p_mp) {
5221 first_frame = 1;
5222 DEBUG_PRINT_ERROR("\nParse nal to get the profile");
5223 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5224 NALU_TYPE_SPS);
5225 m_profile = h264_parser->get_profile();
5226 ret = is_video_session_supported();
5227 if (ret) {
5228 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5229 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5230 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5231 m_state = OMX_StateInvalid;
5232 return OMX_ErrorNone;
5233 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005234 }
5235
Arun Menon906de572013-06-18 17:01:40 -07005236 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5237 /*for use buffer we need to memcpy the data*/
5238 temp_buffer->buffer_len = buffer->nFilledLen;
5239
5240 if (input_use_buffer) {
5241 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5242 if (arbitrary_bytes) {
5243 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5244 } else {
5245 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5246 buffer->nFilledLen);
5247 }
5248 } else {
5249 return OMX_ErrorBadParameter;
5250 }
5251
5252 }
5253
5254 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5255 frameinfo.client_data = (void *) buffer;
5256 frameinfo.datalen = temp_buffer->buffer_len;
5257 frameinfo.flags = 0;
5258 frameinfo.offset = buffer->nOffset;
5259 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5260 frameinfo.pmem_offset = temp_buffer->offset;
5261 frameinfo.timestamp = buffer->nTimeStamp;
5262 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5263 DEBUG_PRINT_LOW("ETB: dmx enabled");
5264 if (m_demux_entries == 0) {
5265 extract_demux_addr_offsets(buffer);
5266 }
5267
5268 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5269 handle_demux_data(buffer);
5270 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5271 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5272 } else {
5273 frameinfo.desc_addr = NULL;
5274 frameinfo.desc_size = 0;
5275 }
5276 if (!arbitrary_bytes) {
5277 frameinfo.flags |= buffer->nFlags;
5278 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005279
5280#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005281 if (m_debug_timestamp) {
5282 if (arbitrary_bytes) {
5283 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5284 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5285 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5286 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5287 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5288 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005289 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005290#endif
5291
5292#ifdef INPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07005293 if (output_capability == V4L2_PIX_FMT_VP8) {
5294 struct vp8_ivf_frame_header {
5295 OMX_U32 framesize;
5296 OMX_U32 timestamp_lo;
5297 OMX_U32 timestamp_hi;
5298 } vp8_frame_header;
5299 vp8_frame_header.framesize = temp_buffer->buffer_len;
5300 /* Currently FW doesn't use timestamp values */
5301 vp8_frame_header.timestamp_lo = 0;
5302 vp8_frame_header.timestamp_hi = 0;
5303 if (inputBufferFile1) {
5304 fwrite((const char *)&vp8_frame_header,
5305 sizeof(vp8_frame_header),1,inputBufferFile1);
5306 fwrite((const char *)temp_buffer->bufferaddr,
5307 temp_buffer->buffer_len,1,inputBufferFile1);
5308 }
5309 } else {
5310 if (inputBufferFile1) {
5311 fwrite((const char *)temp_buffer->bufferaddr,
5312 temp_buffer->buffer_len,1,inputBufferFile1);
5313 }
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07005314 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005315#endif
5316
Arun Menon906de572013-06-18 17:01:40 -07005317 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
5318 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5319 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5320 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005321
Arun Menon906de572013-06-18 17:01:40 -07005322 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5323 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5324 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5325 h264_scratch.nFilledLen = 0;
5326 nal_count = 0;
5327 look_ahead_nal = false;
5328 frame_count = 0;
5329 if (m_frame_parser.mutils)
5330 m_frame_parser.mutils->initialize_frame_checking_environment();
5331 m_frame_parser.flush();
5332 h264_last_au_ts = LLONG_MAX;
5333 h264_last_au_flags = 0;
5334 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5335 m_demux_entries = 0;
5336 }
5337 struct v4l2_buffer buf;
5338 struct v4l2_plane plane;
5339 memset( (void *)&buf, 0, sizeof(buf));
5340 memset( (void *)&plane, 0, sizeof(plane));
5341 int rc;
5342 unsigned long print_count;
5343 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5344 buf.flags = V4L2_BUF_FLAG_EOS;
5345 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
5346 }
5347 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5348 buf.index = nPortIndex;
5349 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5350 buf.memory = V4L2_MEMORY_USERPTR;
5351 plane.bytesused = temp_buffer->buffer_len;
5352 plane.length = drv_ctx.ip_buf.buffer_size;
5353 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5354 (unsigned long)temp_buffer->offset;
5355 plane.reserved[0] = temp_buffer->pmem_fd;
5356 plane.reserved[1] = temp_buffer->offset;
5357 plane.data_offset = 0;
5358 buf.m.planes = &plane;
5359 buf.length = 1;
5360 if (frameinfo.timestamp >= LLONG_MAX) {
5361 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5362 }
5363 //assumption is that timestamp is in milliseconds
5364 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5365 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5366 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5367 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005368
Arun Menon906de572013-06-18 17:01:40 -07005369 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5370 if (rc) {
5371 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5372 return OMX_ErrorHardware;
5373 }
5374 if (!streaming[OUTPUT_PORT]) {
5375 enum v4l2_buf_type buf_type;
5376 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005377
Arun Menon906de572013-06-18 17:01:40 -07005378 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005379 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
Arun Menon906de572013-06-18 17:01:40 -07005380 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5381 if (!ret) {
5382 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
5383 streaming[OUTPUT_PORT] = true;
5384 } else {
5385 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
5386 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5387 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5388 OMX_COMPONENT_GENERATE_EBD);
5389 return OMX_ErrorBadParameter;
5390 }
5391 }
5392 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5393 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5394 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005395
Arun Menon906de572013-06-18 17:01:40 -07005396 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005397}
5398
5399/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005400 FUNCTION
5401 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005402
Arun Menon906de572013-06-18 17:01:40 -07005403 DESCRIPTION
5404 IL client uses this method to release the frame buffer
5405 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005406
Arun Menon906de572013-06-18 17:01:40 -07005407 PARAMETERS
5408 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005409
Arun Menon906de572013-06-18 17:01:40 -07005410 RETURN VALUE
5411 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005412
Arun Menon906de572013-06-18 17:01:40 -07005413 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005414OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005415 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005416{
5417
Arun Menon906de572013-06-18 17:01:40 -07005418 if (m_state == OMX_StateInvalid) {
5419 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5420 return OMX_ErrorInvalidState;
5421 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005422
Arun Menon906de572013-06-18 17:01:40 -07005423 if (!m_out_bEnabled) {
5424 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5425 return OMX_ErrorIncorrectStateOperation;
5426 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005427
Arun Menon906de572013-06-18 17:01:40 -07005428 if (buffer == NULL ||
5429 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) {
5430 return OMX_ErrorBadParameter;
5431 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005432
Arun Menon906de572013-06-18 17:01:40 -07005433 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
5434 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
5435 return OMX_ErrorBadPortIndex;
5436 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005437
Arun Menon906de572013-06-18 17:01:40 -07005438 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5439 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5440 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005441}
5442/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005443 FUNCTION
5444 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005445
Arun Menon906de572013-06-18 17:01:40 -07005446 DESCRIPTION
5447 IL client uses this method to release the frame buffer
5448 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005449
Arun Menon906de572013-06-18 17:01:40 -07005450 PARAMETERS
5451 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005452
Arun Menon906de572013-06-18 17:01:40 -07005453 RETURN VALUE
5454 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005455
Arun Menon906de572013-06-18 17:01:40 -07005456 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005457OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005458 OMX_IN OMX_HANDLETYPE hComp,
5459 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005460{
Arun Menon906de572013-06-18 17:01:40 -07005461 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5462 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5463 unsigned nPortIndex = 0;
5464 struct vdec_fillbuffer_cmd fillbuffer;
5465 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5466 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005467
Arun Menon906de572013-06-18 17:01:40 -07005468 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005469
Arun Menon906de572013-06-18 17:01:40 -07005470 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5471 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005472
Arun Menon906de572013-06-18 17:01:40 -07005473 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5474 bufferAdd, bufferAdd->pBuffer);
5475 /*Return back the output buffer to client*/
5476 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
5477 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5478 buffer->nFilledLen = 0;
5479 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5480 return OMX_ErrorNone;
5481 }
5482 pending_output_buffers++;
5483 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5484 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5485 if (ptr_respbuffer) {
5486 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5487 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005488
Arun Menon906de572013-06-18 17:01:40 -07005489 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5490 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5491 buffer->nFilledLen = 0;
5492 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5493 pending_output_buffers--;
5494 return OMX_ErrorBadParameter;
5495 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005496
Arun Menon906de572013-06-18 17:01:40 -07005497 int rc = 0;
5498 struct v4l2_buffer buf;
5499 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5500 memset( (void *)&buf, 0, sizeof(buf));
5501 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5502 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005503
Arun Menon906de572013-06-18 17:01:40 -07005504 buf.index = nPortIndex;
5505 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5506 buf.memory = V4L2_MEMORY_USERPTR;
5507 plane[0].bytesused = buffer->nFilledLen;
5508 plane[0].length = drv_ctx.op_buf.buffer_size;
5509 plane[0].m.userptr =
5510 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5511 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5512 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5513 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5514 plane[0].data_offset = 0;
5515 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5516 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5517 plane[extra_idx].bytesused = 0;
5518 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5519 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 -07005520#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005521 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005522#endif
Arun Menon906de572013-06-18 17:01:40 -07005523 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5524 plane[extra_idx].data_offset = 0;
5525 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5526 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5527 return OMX_ErrorBadParameter;
5528 }
5529 buf.m.planes = plane;
5530 buf.length = drv_ctx.num_planes;
5531 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5532 if (rc) {
5533 /*TODO: How to handle this case */
5534 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5535 }
Arun Menon906de572013-06-18 17:01:40 -07005536return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005537}
5538
5539/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005540 FUNCTION
5541 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005542
Arun Menon906de572013-06-18 17:01:40 -07005543 DESCRIPTION
5544 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005545
Arun Menon906de572013-06-18 17:01:40 -07005546 PARAMETERS
5547 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005548
Arun Menon906de572013-06-18 17:01:40 -07005549 RETURN VALUE
5550 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005551
Arun Menon906de572013-06-18 17:01:40 -07005552 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005553OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005554 OMX_IN OMX_CALLBACKTYPE* callbacks,
5555 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005556{
5557
Arun Menon906de572013-06-18 17:01:40 -07005558 m_cb = *callbacks;
5559 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5560 m_cb.EventHandler,m_cb.FillBufferDone);
5561 m_app_data = appData;
5562 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005563}
5564
5565/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005566 FUNCTION
5567 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005568
Arun Menon906de572013-06-18 17:01:40 -07005569 DESCRIPTION
5570 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005571
Arun Menon906de572013-06-18 17:01:40 -07005572 PARAMETERS
5573 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005574
Arun Menon906de572013-06-18 17:01:40 -07005575 RETURN VALUE
5576 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005577
Arun Menon906de572013-06-18 17:01:40 -07005578 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005579OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5580{
5581#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005582 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005583 delete iDivXDrmDecrypt;
5584 iDivXDrmDecrypt=NULL;
5585 }
5586#endif //_ANDROID_
5587
Shalaj Jain286b0062013-02-21 20:35:48 -08005588 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005589 if (OMX_StateLoaded != m_state) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005590 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
Arun Menon906de572013-06-18 17:01:40 -07005591 m_state);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005592 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005593 } else {
5594 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005595 }
5596
5597 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005598 if (m_out_mem_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005599 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005600 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5601 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005602 }
5603#ifdef _ANDROID_ICS_
5604 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5605#endif
5606 }
5607
5608 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005609 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005610 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005611 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5612 if (m_inp_mem_ptr)
5613 free_input_buffer (i,&m_inp_mem_ptr[i]);
5614 else
5615 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005616 }
5617 }
5618 free_input_buffer_header();
5619 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005620 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005621 free(h264_scratch.pBuffer);
5622 h264_scratch.pBuffer = NULL;
5623 }
5624
Arun Menon906de572013-06-18 17:01:40 -07005625 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005626 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005627 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005628 }
5629
Arun Menon906de572013-06-18 17:01:40 -07005630 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005631 free(m_platform_list);
5632 m_platform_list = NULL;
5633 }
Arun Menon906de572013-06-18 17:01:40 -07005634 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005635 free(m_vendor_config.pData);
5636 m_vendor_config.pData = NULL;
5637 }
5638
5639 // Reset counters in mesg queues
5640 m_ftb_q.m_size=0;
5641 m_cmd_q.m_size=0;
5642 m_etb_q.m_size=0;
5643 m_ftb_q.m_read = m_ftb_q.m_write =0;
5644 m_cmd_q.m_read = m_cmd_q.m_write =0;
5645 m_etb_q.m_read = m_etb_q.m_write =0;
5646#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005647 if (m_debug_timestamp) {
5648 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005649 }
5650#endif
5651
5652 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
5653 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07005654 // NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005655 DEBUG_PRINT_HIGH("\n Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07005656
Shalaj Jain273b3e02012-06-22 19:08:03 -07005657#ifdef INPUT_BUFFER_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07005658 if (inputBufferFile1)
5659 fclose (inputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005660#endif
5661#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07005662 if (outputBufferFile1)
Shalaj Jainaf08f302013-03-18 13:15:35 -07005663 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005664#endif
5665#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07005666 if (outputExtradataFile)
5667 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005668#endif
Arun Menon906de572013-06-18 17:01:40 -07005669 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
5670 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005671}
5672
5673/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005674 FUNCTION
5675 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07005676
Arun Menon906de572013-06-18 17:01:40 -07005677 DESCRIPTION
5678 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005679
Arun Menon906de572013-06-18 17:01:40 -07005680 PARAMETERS
5681 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005682
Arun Menon906de572013-06-18 17:01:40 -07005683 RETURN VALUE
5684 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005685
Arun Menon906de572013-06-18 17:01:40 -07005686 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005687OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005688 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5689 OMX_IN OMX_U32 port,
5690 OMX_IN OMX_PTR appData,
5691 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005692{
Arun Menon906de572013-06-18 17:01:40 -07005693 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
5694 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
5695 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005696
5697#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005698 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
5699 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005700#else
Arun Menon906de572013-06-18 17:01:40 -07005701 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005702#endif
Arun Menon906de572013-06-18 17:01:40 -07005703 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
5704 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
5705 DEBUG_PRINT_ERROR("\n ");
5706 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005707#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005708 if (m_display_id == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005709 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
5710 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005711 }
5712 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
5713 eglGetProcAddress("eglQueryImageKHR");
5714 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
5715 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
5716 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005717#else //with OMX test app
5718 struct temp_egl {
5719 int pmem_fd;
5720 int offset;
5721 };
5722 struct temp_egl *temp_egl_id = NULL;
5723 void * pmemPtr = (void *) eglImage;
5724 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07005725 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005726 fd = temp_egl_id->pmem_fd;
5727 offset = temp_egl_id->offset;
5728 }
5729#endif
5730 if (fd < 0) {
5731 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
5732 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005733 }
5734 pmem_info.pmem_fd = (OMX_U32) fd;
5735 pmem_info.offset = (OMX_U32) offset;
5736 pmem_entry.entry = (void *) &pmem_info;
5737 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5738 pmem_list.entryList = &pmem_entry;
5739 pmem_list.nEntries = 1;
5740 ouput_egl_buffers = true;
5741 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
5742 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
5743 (OMX_U8 *)pmemPtr)) {
5744 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
5745 return OMX_ErrorInsufficientResources;
5746 }
5747 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005748}
5749
5750/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005751 FUNCTION
5752 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07005753
Arun Menon906de572013-06-18 17:01:40 -07005754 DESCRIPTION
5755 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005756
Arun Menon906de572013-06-18 17:01:40 -07005757 PARAMETERS
5758 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005759
Arun Menon906de572013-06-18 17:01:40 -07005760 RETURN VALUE
5761 OMX Error None if everything is successful.
5762 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005763OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005764 OMX_OUT OMX_U8* role,
5765 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005766{
Arun Menon906de572013-06-18 17:01:40 -07005767 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005768
Arun Menon906de572013-06-18 17:01:40 -07005769 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
5770 if ((0 == index) && role) {
5771 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
5772 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5773 } else {
5774 eRet = OMX_ErrorNoMore;
5775 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005776 }
Arun Menon906de572013-06-18 17:01:40 -07005777 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
5778 if ((0 == index) && role) {
5779 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
5780 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5781 } else {
5782 eRet = OMX_ErrorNoMore;
5783 }
5784 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
5785 if ((0 == index) && role) {
5786 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
5787 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5788 } else {
5789 DEBUG_PRINT_LOW("\n No more roles \n");
5790 eRet = OMX_ErrorNoMore;
5791 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005792 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005793
Arun Menon906de572013-06-18 17:01:40 -07005794 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
5795 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
5796 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07005797
Shalaj Jain273b3e02012-06-22 19:08:03 -07005798 {
Arun Menon906de572013-06-18 17:01:40 -07005799 if ((0 == index) && role) {
5800 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
5801 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5802 } else {
5803 DEBUG_PRINT_LOW("\n No more roles \n");
5804 eRet = OMX_ErrorNoMore;
5805 }
5806 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
5807 if ((0 == index) && role) {
5808 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
5809 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5810 } else {
5811 DEBUG_PRINT_LOW("\n No more roles \n");
5812 eRet = OMX_ErrorNoMore;
5813 }
5814 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
5815 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
5816 ) {
5817 if ((0 == index) && role) {
5818 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
5819 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5820 } else {
5821 DEBUG_PRINT_LOW("\n No more roles \n");
5822 eRet = OMX_ErrorNoMore;
5823 }
5824 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
5825 if ((0 == index) && role) {
5826 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
5827 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5828 } else {
5829 DEBUG_PRINT_LOW("\n No more roles \n");
5830 eRet = OMX_ErrorNoMore;
5831 }
5832 } else {
5833 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
5834 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005835 }
Arun Menon906de572013-06-18 17:01:40 -07005836 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005837}
5838
5839
5840
5841
5842/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005843 FUNCTION
5844 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07005845
Arun Menon906de572013-06-18 17:01:40 -07005846 DESCRIPTION
5847 Checks if entire buffer pool is allocated by IL Client or not.
5848 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005849
Arun Menon906de572013-06-18 17:01:40 -07005850 PARAMETERS
5851 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005852
Arun Menon906de572013-06-18 17:01:40 -07005853 RETURN VALUE
5854 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005855
Arun Menon906de572013-06-18 17:01:40 -07005856 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005857bool omx_vdec::allocate_done(void)
5858{
Arun Menon906de572013-06-18 17:01:40 -07005859 bool bRet = false;
5860 bool bRet_In = false;
5861 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005862
Arun Menon906de572013-06-18 17:01:40 -07005863 bRet_In = allocate_input_done();
5864 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005865
Arun Menon906de572013-06-18 17:01:40 -07005866 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005867 bRet = true;
5868 }
Arun Menon906de572013-06-18 17:01:40 -07005869
5870 return bRet;
5871}
5872/* ======================================================================
5873 FUNCTION
5874 omx_vdec::AllocateInputDone
5875
5876 DESCRIPTION
5877 Checks if I/P buffer pool is allocated by IL Client or not.
5878
5879 PARAMETERS
5880 None.
5881
5882 RETURN VALUE
5883 true/false.
5884
5885 ========================================================================== */
5886bool omx_vdec::allocate_input_done(void)
5887{
5888 bool bRet = false;
5889 unsigned i=0;
5890
5891 if (m_inp_mem_ptr == NULL) {
5892 return bRet;
5893 }
5894 if (m_inp_mem_ptr ) {
5895 for (; i<drv_ctx.ip_buf.actualcount; i++) {
5896 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
5897 break;
5898 }
5899 }
5900 }
5901 if (i == drv_ctx.ip_buf.actualcount) {
5902 bRet = true;
5903 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
5904 }
5905 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
5906 m_inp_bPopulated = OMX_TRUE;
5907 }
5908 return bRet;
5909}
5910/* ======================================================================
5911 FUNCTION
5912 omx_vdec::AllocateOutputDone
5913
5914 DESCRIPTION
5915 Checks if entire O/P buffer pool is allocated by IL Client or not.
5916
5917 PARAMETERS
5918 None.
5919
5920 RETURN VALUE
5921 true/false.
5922
5923 ========================================================================== */
5924bool omx_vdec::allocate_output_done(void)
5925{
5926 bool bRet = false;
5927 unsigned j=0;
5928
5929 if (m_out_mem_ptr == NULL) {
5930 return bRet;
5931 }
5932
5933 if (m_out_mem_ptr) {
5934 for (; j < drv_ctx.op_buf.actualcount; j++) {
5935 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
5936 break;
5937 }
5938 }
5939 }
5940
5941 if (j == drv_ctx.op_buf.actualcount) {
5942 bRet = true;
5943 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
5944 if (m_out_bEnabled)
5945 m_out_bPopulated = OMX_TRUE;
5946 }
5947
5948 return bRet;
5949}
5950
5951/* ======================================================================
5952 FUNCTION
5953 omx_vdec::ReleaseDone
5954
5955 DESCRIPTION
5956 Checks if IL client has released all the buffers.
5957
5958 PARAMETERS
5959 None.
5960
5961 RETURN VALUE
5962 true/false
5963
5964 ========================================================================== */
5965bool omx_vdec::release_done(void)
5966{
5967 bool bRet = false;
5968
5969 if (release_input_done()) {
5970 if (release_output_done()) {
5971 bRet = true;
5972 }
5973 }
5974 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005975}
5976
5977
5978/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005979 FUNCTION
5980 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07005981
Arun Menon906de572013-06-18 17:01:40 -07005982 DESCRIPTION
5983 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005984
Arun Menon906de572013-06-18 17:01:40 -07005985 PARAMETERS
5986 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005987
Arun Menon906de572013-06-18 17:01:40 -07005988 RETURN VALUE
5989 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005990
Arun Menon906de572013-06-18 17:01:40 -07005991 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005992bool omx_vdec::release_output_done(void)
5993{
Arun Menon906de572013-06-18 17:01:40 -07005994 bool bRet = false;
5995 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005996
Arun Menon906de572013-06-18 17:01:40 -07005997 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
5998 if (m_out_mem_ptr) {
5999 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6000 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6001 break;
6002 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006003 }
Arun Menon906de572013-06-18 17:01:40 -07006004 if (j == drv_ctx.op_buf.actualcount) {
6005 m_out_bm_count = 0;
6006 bRet = true;
6007 }
6008 } else {
6009 m_out_bm_count = 0;
6010 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006011 }
Arun Menon906de572013-06-18 17:01:40 -07006012 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006013}
6014/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006015 FUNCTION
6016 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006017
Arun Menon906de572013-06-18 17:01:40 -07006018 DESCRIPTION
6019 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006020
Arun Menon906de572013-06-18 17:01:40 -07006021 PARAMETERS
6022 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006023
Arun Menon906de572013-06-18 17:01:40 -07006024 RETURN VALUE
6025 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006026
Arun Menon906de572013-06-18 17:01:40 -07006027 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006028bool omx_vdec::release_input_done(void)
6029{
Arun Menon906de572013-06-18 17:01:40 -07006030 bool bRet = false;
6031 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006032
Arun Menon906de572013-06-18 17:01:40 -07006033 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6034 if (m_inp_mem_ptr) {
6035 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6036 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6037 break;
6038 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006039 }
Arun Menon906de572013-06-18 17:01:40 -07006040 if (j==drv_ctx.ip_buf.actualcount) {
6041 bRet = true;
6042 }
6043 } else {
6044 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006045 }
Arun Menon906de572013-06-18 17:01:40 -07006046 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006047}
6048
6049OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006050 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006051{
Arun Menon906de572013-06-18 17:01:40 -07006052 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6053 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) {
6054 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6055 return OMX_ErrorBadParameter;
6056 } else if (output_flush_progress) {
6057 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6058 buffer->nFilledLen = 0;
6059 buffer->nTimeStamp = 0;
6060 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6061 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6062 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006063 }
6064
Arun Menon906de572013-06-18 17:01:40 -07006065 if (m_debug_extradata) {
6066 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
6067 DEBUG_PRINT_HIGH("\n");
6068 DEBUG_PRINT_HIGH("***************************************************\n");
6069 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
6070 DEBUG_PRINT_HIGH("***************************************************\n");
6071 }
6072
6073 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
6074 DEBUG_PRINT_HIGH("\n");
6075 DEBUG_PRINT_HIGH("***************************************************\n");
6076 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
6077 DEBUG_PRINT_HIGH("***************************************************\n");
6078 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006079 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006080
6081
Arun Menon906de572013-06-18 17:01:40 -07006082 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6083 buffer, buffer->pBuffer);
6084 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006085
Arun Menon906de572013-06-18 17:01:40 -07006086 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6087 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6088 if (!output_flush_progress)
6089 post_event((unsigned)NULL, (unsigned)NULL,
6090 OMX_COMPONENT_GENERATE_EOS_DONE);
6091
6092 if (psource_frame) {
6093 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6094 psource_frame = NULL;
6095 }
6096 if (pdest_frame) {
6097 pdest_frame->nFilledLen = 0;
6098 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6099 (unsigned)NULL);
6100 pdest_frame = NULL;
6101 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006102 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006103
Arun Menon906de572013-06-18 17:01:40 -07006104 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006105#ifdef OUTPUT_BUFFER_LOG
Arun Menon906de572013-06-18 17:01:40 -07006106 if (outputBufferFile1 && buffer->nFilledLen) {
6107 int buf_index = buffer - m_out_mem_ptr;
6108 int stride = drv_ctx.video_resolution.stride;
6109 int scanlines = drv_ctx.video_resolution.scan_lines;
6110 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
6111 unsigned i;
6112 int bytes_written = 0;
6113 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6114 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6115 temp += stride;
6116 }
6117 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
6118 int stride_c = stride;
6119 for (i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6120 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6121 temp += stride_c;
6122 }
6123 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006124#endif
6125
Arun Menon906de572013-06-18 17:01:40 -07006126 /* For use buffer we need to copy the data */
6127 if (!output_flush_progress) {
6128 /* This is the error check for non-recoverable errros */
6129 bool is_duplicate_ts_valid = true;
6130 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006131
Arun Menon906de572013-06-18 17:01:40 -07006132 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6133 output_capability == V4L2_PIX_FMT_MPEG2 ||
6134 output_capability == V4L2_PIX_FMT_DIVX ||
6135 output_capability == V4L2_PIX_FMT_DIVX_311)
6136 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006137
Arun Menon906de572013-06-18 17:01:40 -07006138 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6139 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6140 if (mbaff) {
6141 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306142 }
Arun Menon906de572013-06-18 17:01:40 -07006143 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306144
Arun Menon906de572013-06-18 17:01:40 -07006145 if (buffer->nFilledLen > 0) {
6146 time_stamp_dts.get_next_timestamp(buffer,
6147 is_interlaced && is_duplicate_ts_valid);
6148 if (m_debug_timestamp) {
6149 {
6150 OMX_TICKS expected_ts = 0;
6151 m_timestamp_list.pop_min_ts(expected_ts);
6152 if (is_interlaced && is_duplicate_ts_valid) {
6153 m_timestamp_list.pop_min_ts(expected_ts);
6154 }
6155 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6156 buffer->nTimeStamp, expected_ts);
6157
6158 if (buffer->nTimeStamp != expected_ts) {
6159 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6160 }
6161 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306162 }
Arun Menon906de572013-06-18 17:01:40 -07006163 } else {
6164 m_inp_err_count++;
6165 time_stamp_dts.remove_time_stamp(
6166 buffer->nTimeStamp,
6167 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306168 }
Arun Menon906de572013-06-18 17:01:40 -07006169
6170
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006171 }
Arun Menon906de572013-06-18 17:01:40 -07006172 if (m_cb.FillBufferDone) {
6173 if (buffer->nFilledLen > 0) {
6174 handle_extradata(buffer);
6175 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6176 set_frame_rate(buffer->nTimeStamp);
6177 else if (arbitrary_bytes)
6178 adjust_timestamp(buffer->nTimeStamp);
6179 if (perf_flag) {
6180 if (!proc_frms) {
6181 dec_time.stop();
6182 latency = dec_time.processing_time_us() - latency;
6183 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6184 dec_time.start();
6185 fps_metrics.start();
6186 }
6187 proc_frms++;
6188 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6189 OMX_U64 proc_time = 0;
6190 fps_metrics.stop();
6191 proc_time = fps_metrics.processing_time_us();
6192 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006193 proc_frms, (float)proc_time / 1e6,
6194 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006195 proc_frms = 0;
6196 }
6197 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006198
6199#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006200 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006201
Arun Menon906de572013-06-18 17:01:40 -07006202 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6203 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6204 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6205 buffer->nFilledLen + 3)&(~3));
6206 while (p_extra &&
6207 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
6208 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6209 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6210 if (p_extra->eType == OMX_ExtraDataNone) {
6211 break;
6212 }
6213 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6214 }
6215 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006216#endif
Arun Menon906de572013-06-18 17:01:40 -07006217 }
6218 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6219 prev_ts = LLONG_MAX;
6220 rst_prev_ts = true;
6221 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006222
Arun Menon906de572013-06-18 17:01:40 -07006223 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6224 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6225 buffer->pPlatformPrivate)->entryList->entry;
6226 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006227 OMX_BUFFERHEADERTYPE *il_buffer;
6228 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6229 if (il_buffer)
6230 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6231 else {
6232 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6233 return OMX_ErrorBadParameter;
6234 }
6235 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
6236 } else {
6237 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006238 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006239
Arun Menon906de572013-06-18 17:01:40 -07006240 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006241}
6242
6243OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006244 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006245{
6246
Arun Menon906de572013-06-18 17:01:40 -07006247 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006248 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006249 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006250 }
6251
6252 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006253 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006254 pending_input_buffers--;
6255
Arun Menon906de572013-06-18 17:01:40 -07006256 if (arbitrary_bytes) {
6257 if (pdest_frame == NULL && input_flush_progress == false) {
6258 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6259 pdest_frame = buffer;
6260 buffer->nFilledLen = 0;
6261 buffer->nTimeStamp = LLONG_MAX;
6262 push_input_buffer (hComp);
6263 } else {
6264 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6265 buffer->nFilledLen = 0;
6266 if (!m_input_free_q.insert_entry((unsigned)buffer,
6267 (unsigned)NULL, (unsigned)NULL)) {
6268 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6269 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006270 }
Arun Menon906de572013-06-18 17:01:40 -07006271 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006272 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006273 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006274 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6275 }
6276 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6277 }
6278 return OMX_ErrorNone;
6279}
6280
Shalaj Jain273b3e02012-06-22 19:08:03 -07006281int omx_vdec::async_message_process (void *context, void* message)
6282{
Arun Menon906de572013-06-18 17:01:40 -07006283 omx_vdec* omx = NULL;
6284 struct vdec_msginfo *vdec_msg = NULL;
6285 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6286 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6287 struct vdec_output_frameinfo *output_respbuf = NULL;
6288 int rc=1;
6289 if (context == NULL || message == NULL) {
6290 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6291 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006292 }
Arun Menon906de572013-06-18 17:01:40 -07006293 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006294
Arun Menon906de572013-06-18 17:01:40 -07006295 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006296
Arun Menon906de572013-06-18 17:01:40 -07006297 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006298
Arun Menon906de572013-06-18 17:01:40 -07006299 case VDEC_MSG_EVT_HW_ERROR:
6300 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6301 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6302 break;
6303
6304 case VDEC_MSG_RESP_START_DONE:
6305 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6306 OMX_COMPONENT_GENERATE_START_DONE);
6307 break;
6308
6309 case VDEC_MSG_RESP_STOP_DONE:
6310 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6311 OMX_COMPONENT_GENERATE_STOP_DONE);
6312 break;
6313
6314 case VDEC_MSG_RESP_RESUME_DONE:
6315 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6316 OMX_COMPONENT_GENERATE_RESUME_DONE);
6317 break;
6318
6319 case VDEC_MSG_RESP_PAUSE_DONE:
6320 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6321 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6322 break;
6323
6324 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6325 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6326 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6327 break;
6328 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6329 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6330 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6331 break;
6332 case VDEC_MSG_RESP_INPUT_FLUSHED:
6333 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6334
6335 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6336 vdec_msg->msgdata.input_frame_clientdata; */
6337
6338 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6339 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6340 if (omxhdr == NULL ||
6341 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) {
6342 omxhdr = NULL;
6343 vdec_msg->status_code = VDEC_S_EFATAL;
6344 }
6345 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6346 DEBUG_PRINT_HIGH("Unsupported input");
6347 omx->omx_report_error ();
6348 }
6349 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6350 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6351 }
6352 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6353 OMX_COMPONENT_GENERATE_EBD);
6354 break;
6355 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6356 int64_t *timestamp;
6357 timestamp = (int64_t *) malloc(sizeof(int64_t));
6358 if (timestamp) {
6359 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6360 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6361 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6362 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6363 vdec_msg->msgdata.output_frame.time_stamp);
6364 }
6365 break;
6366 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6367 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6368
6369 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6370 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6371 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6372 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6373 vdec_msg->msgdata.output_frame.pic_type);
6374
6375 if (omxhdr && omxhdr->pOutputPortPrivate &&
6376 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6377 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6378 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) {
6379 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6380 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6381 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6382 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6383 omxhdr->nFlags = 0;
6384
6385 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS) {
6386 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6387 //rc = -1;
6388 }
6389 if (omxhdr->nFilledLen) {
6390 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6391 }
6392 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6393 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6394 } else {
6395 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6396 }
6397 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6398 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6399 }
6400 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6401 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6402 }
6403 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6404 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
6405 !(v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006406 omx->time_stamp_dts.remove_time_stamp(
6407 omxhdr->nTimeStamp,
6408 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6409 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006410 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6411 OMX_COMPONENT_GENERATE_FTB);
6412 break;
6413 }
6414 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6415 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6416 }
6417 vdec_msg->msgdata.output_frame.bufferaddr =
6418 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6419 int format_notably_changed = 0;
6420 if (omxhdr->nFilledLen &&
6421 (omxhdr->nFilledLen != omx->prev_n_filled_len)) {
6422 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6423 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6424 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
6425 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6426 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6427 format_notably_changed = 1;
6428 }
6429 }
6430 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6431 vdec_msg->msgdata.output_frame.framesize.left)
6432 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6433 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6434 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6435 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6436 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6437 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6438 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6439 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
6440 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6441 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6442 }
6443 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
6444 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6445 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006446 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6447 omx->drv_ctx.video_resolution.frame_width) {
6448 vdec_msg->msgdata.output_frame.framesize.left = 0;
6449 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6450 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6451 }
6452 }
6453 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6454 omx->drv_ctx.video_resolution.frame_height) {
6455 vdec_msg->msgdata.output_frame.framesize.top = 0;
6456 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6457 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6458 }
6459 }
6460 DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d\n",
6461 vdec_msg->msgdata.output_frame.framesize.left,
6462 vdec_msg->msgdata.output_frame.framesize.top,
6463 vdec_msg->msgdata.output_frame.framesize.right,
6464 vdec_msg->msgdata.output_frame.framesize.bottom,
6465 omx->drv_ctx.video_resolution.frame_width,
6466 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006467 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6468 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6469 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6470 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6471 format_notably_changed = 1;
6472 }
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006473 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d\n",
6474 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6475 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006476 if (format_notably_changed) {
6477 if (omx->is_video_session_supported()) {
6478 omx->post_event (NULL, vdec_msg->status_code,
6479 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6480 } else {
6481 if (!omx->client_buffers.update_buffer_req()) {
6482 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6483 }
6484 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6485 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6486 }
6487 }
6488 if (omxhdr->nFilledLen)
6489 omx->prev_n_filled_len = omxhdr->nFilledLen;
6490
6491 output_respbuf = (struct vdec_output_frameinfo *)\
6492 omxhdr->pOutputPortPrivate;
6493 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6494 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6495 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6496 output_respbuf->pic_type = PICTURE_TYPE_I;
6497 }
6498 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6499 output_respbuf->pic_type = PICTURE_TYPE_P;
6500 }
6501 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6502 output_respbuf->pic_type = PICTURE_TYPE_B;
6503 }
6504
6505 if (omx->output_use_buffer)
6506 memcpy ( omxhdr->pBuffer, (void *)
6507 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6508 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6509 vdec_msg->msgdata.output_frame.len);
6510 } else
6511 omxhdr->nFilledLen = 0;
6512 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6513 OMX_COMPONENT_GENERATE_FBD);
6514 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6515 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6516 OMX_COMPONENT_GENERATE_EOS_DONE);
6517 else
6518 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6519 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6520 break;
6521 case VDEC_MSG_EVT_CONFIG_CHANGED:
6522 DEBUG_PRINT_HIGH("\n Port settings changed");
6523 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6524 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6525 break;
6526 default:
6527 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006528 }
Arun Menon906de572013-06-18 17:01:40 -07006529 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006530}
6531
6532OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006533 OMX_HANDLETYPE hComp,
6534 OMX_BUFFERHEADERTYPE *buffer
6535 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006536{
Arun Menon906de572013-06-18 17:01:40 -07006537 unsigned address,p2,id;
6538 DEBUG_PRINT_LOW("\n Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006539
Arun Menon906de572013-06-18 17:01:40 -07006540 if (buffer == NULL) {
6541 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006542 }
Arun Menon906de572013-06-18 17:01:40 -07006543 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6544 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
6545 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6546
6547 /* return zero length and not an EOS buffer */
6548 /* return buffer if input flush in progress */
6549 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6550 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
6551 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
6552 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6553 return OMX_ErrorNone;
6554 }
6555
6556 if (psource_frame == NULL) {
6557 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
6558 psource_frame = buffer;
6559 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
6560 push_input_buffer (hComp);
6561 } else {
6562 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
6563 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6564 (unsigned)NULL)) {
6565 return OMX_ErrorBadParameter;
6566 }
6567 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006568
6569
Arun Menon906de572013-06-18 17:01:40 -07006570 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006571}
6572
6573OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6574{
Arun Menon906de572013-06-18 17:01:40 -07006575 unsigned address,p2,id;
6576 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006577
Arun Menon906de572013-06-18 17:01:40 -07006578 if (pdest_frame == NULL || psource_frame == NULL) {
6579 /*Check if we have a destination buffer*/
6580 if (pdest_frame == NULL) {
6581 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
6582 if (m_input_free_q.m_size) {
6583 m_input_free_q.pop_entry(&address,&p2,&id);
6584 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6585 pdest_frame->nFilledLen = 0;
6586 pdest_frame->nTimeStamp = LLONG_MAX;
6587 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
6588 }
6589 }
6590
6591 /*Check if we have a destination buffer*/
6592 if (psource_frame == NULL) {
6593 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
6594 if (m_input_pending_q.m_size) {
6595 m_input_pending_q.pop_entry(&address,&p2,&id);
6596 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
6597 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6598 psource_frame->nTimeStamp);
6599 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6600 psource_frame->nFlags,psource_frame->nFilledLen);
6601
6602 }
6603 }
6604
Shalaj Jain273b3e02012-06-22 19:08:03 -07006605 }
6606
Arun Menon906de572013-06-18 17:01:40 -07006607 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6608 switch (codec_type_parse) {
6609 case CODEC_TYPE_MPEG4:
6610 case CODEC_TYPE_H263:
6611 case CODEC_TYPE_MPEG2:
6612 ret = push_input_sc_codec(hComp);
6613 break;
6614 case CODEC_TYPE_H264:
6615 ret = push_input_h264(hComp);
6616 break;
6617 case CODEC_TYPE_VC1:
6618 ret = push_input_vc1(hComp);
6619 break;
6620 default:
6621 break;
6622 }
6623 if (ret != OMX_ErrorNone) {
6624 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
6625 omx_report_error ();
6626 break;
6627 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006628 }
6629
Arun Menon906de572013-06-18 17:01:40 -07006630 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006631}
6632
6633OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
6634{
Arun Menon906de572013-06-18 17:01:40 -07006635 OMX_U32 partial_frame = 1;
6636 OMX_BOOL generate_ebd = OMX_TRUE;
6637 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006638
Arun Menon906de572013-06-18 17:01:40 -07006639 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
6640 psource_frame,psource_frame->nTimeStamp);
6641 if (m_frame_parser.parse_sc_frame(psource_frame,
6642 pdest_frame,&partial_frame) == -1) {
6643 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
6644 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006645 }
Arun Menon906de572013-06-18 17:01:40 -07006646
6647 if (partial_frame == 0) {
6648 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
6649 pdest_frame->nFilledLen,psource_frame,frame_count);
6650
6651
6652 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
6653 /*First Parsed buffer will have only header Hence skip*/
6654 if (frame_count == 0) {
6655 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
6656
6657 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
6658 codec_type_parse == CODEC_TYPE_DIVX) {
6659 mp4StreamType psBits;
6660 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
6661 psBits.numBytes = pdest_frame->nFilledLen;
6662 mp4_headerparser.parseHeader(&psBits);
6663 }
6664
6665 frame_count++;
6666 } else {
6667 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6668 if (pdest_frame->nFilledLen) {
6669 /*Push the frame to the Decoder*/
6670 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6671 return OMX_ErrorBadParameter;
6672 }
6673 frame_count++;
6674 pdest_frame = NULL;
6675
6676 if (m_input_free_q.m_size) {
6677 m_input_free_q.pop_entry(&address,&p2,&id);
6678 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6679 pdest_frame->nFilledLen = 0;
6680 }
6681 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
6682 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
6683 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
6684 (unsigned)NULL);
6685 pdest_frame = NULL;
6686 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006687 }
Arun Menon906de572013-06-18 17:01:40 -07006688 } else {
6689 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
6690 /*Check if Destination Buffer is full*/
6691 if (pdest_frame->nAllocLen ==
6692 pdest_frame->nFilledLen + pdest_frame->nOffset) {
6693 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
6694 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006695 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006696 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006697
Arun Menon906de572013-06-18 17:01:40 -07006698 if (psource_frame->nFilledLen == 0) {
6699 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6700 if (pdest_frame) {
6701 pdest_frame->nFlags |= psource_frame->nFlags;
6702 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
6703 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6704 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6705 pdest_frame->nFilledLen,frame_count++);
6706 /*Push the frame to the Decoder*/
6707 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6708 return OMX_ErrorBadParameter;
6709 }
6710 frame_count++;
6711 pdest_frame = NULL;
6712 } else {
6713 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
6714 generate_ebd = OMX_FALSE;
6715 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006716 }
Arun Menon906de572013-06-18 17:01:40 -07006717 if (generate_ebd) {
6718 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
6719 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6720 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006721
Arun Menon906de572013-06-18 17:01:40 -07006722 if (m_input_pending_q.m_size) {
6723 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6724 m_input_pending_q.pop_entry(&address,&p2,&id);
6725 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6726 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6727 psource_frame->nTimeStamp);
6728 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6729 psource_frame->nFlags,psource_frame->nFilledLen);
6730 }
6731 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006732 }
Arun Menon906de572013-06-18 17:01:40 -07006733 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006734}
6735
6736OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
6737{
Arun Menon906de572013-06-18 17:01:40 -07006738 OMX_U32 partial_frame = 1;
6739 unsigned address = 0, p2 = 0, id = 0;
6740 OMX_BOOL isNewFrame = OMX_FALSE;
6741 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006742
Arun Menon906de572013-06-18 17:01:40 -07006743 if (h264_scratch.pBuffer == NULL) {
6744 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
6745 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006746 }
Arun Menon906de572013-06-18 17:01:40 -07006747 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
6748 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
6749 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
6750 if (h264_scratch.nFilledLen && look_ahead_nal) {
6751 look_ahead_nal = false;
6752 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6753 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006754 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6755 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6756 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Arun Menon906de572013-06-18 17:01:40 -07006757 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006758 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006759 } else {
6760 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006761 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006762 }
Arun Menon906de572013-06-18 17:01:40 -07006763 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07006764
6765 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
6766 in EOS flag getting associated with the destination
6767 */
6768 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
6769 pdest_frame->nFilledLen) {
6770 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
6771 generate_ebd = OMX_FALSE;
6772 }
6773
Arun Menon906de572013-06-18 17:01:40 -07006774 if (nal_length == 0) {
6775 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
6776 if (m_frame_parser.parse_sc_frame(psource_frame,
6777 &h264_scratch,&partial_frame) == -1) {
6778 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006779 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006780 }
Arun Menon906de572013-06-18 17:01:40 -07006781 } else {
6782 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
6783 if (m_frame_parser.parse_h264_nallength(psource_frame,
6784 &h264_scratch,&partial_frame) == -1) {
6785 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
6786 return OMX_ErrorBadParameter;
6787 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006788 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006789
Arun Menon906de572013-06-18 17:01:40 -07006790 if (partial_frame == 0) {
6791 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
6792 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
6793 nal_count++;
6794 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
6795 h264_scratch.nFlags = psource_frame->nFlags;
6796 } else {
6797 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
6798 if (h264_scratch.nFilledLen) {
6799 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
6800 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006801#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07006802 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6803 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
6804 h264_scratch.nFilledLen, NALU_TYPE_SEI);
6805 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
6806 // If timeinfo is present frame info from SEI is already processed
6807 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
6808 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006809#endif
Arun Menon906de572013-06-18 17:01:40 -07006810 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
6811 nal_count++;
6812 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
6813 pdest_frame->nTimeStamp = h264_last_au_ts;
6814 pdest_frame->nFlags = h264_last_au_flags;
6815#ifdef PANSCAN_HDLR
6816 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
6817 h264_parser->update_panscan_data(h264_last_au_ts);
6818#endif
6819 }
6820 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
6821 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
6822 h264_last_au_ts = h264_scratch.nTimeStamp;
6823 h264_last_au_flags = h264_scratch.nFlags;
6824#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
6825 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
6826 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
6827 if (!VALID_TS(h264_last_au_ts))
6828 h264_last_au_ts = ts_in_sei;
6829 }
6830#endif
6831 } else
6832 h264_last_au_ts = LLONG_MAX;
6833 }
6834
6835 if (!isNewFrame) {
6836 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6837 h264_scratch.nFilledLen) {
6838 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
6839 h264_scratch.nFilledLen);
6840 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6841 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6842 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6843 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
6844 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6845 h264_scratch.nFilledLen = 0;
6846 } else {
6847 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
6848 return OMX_ErrorBadParameter;
6849 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07006850 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07006851 look_ahead_nal = true;
6852 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
6853 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6854 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6855 pdest_frame->nFilledLen,frame_count++);
6856
6857 if (pdest_frame->nFilledLen == 0) {
6858 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
6859 look_ahead_nal = false;
6860 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6861 h264_scratch.nFilledLen) {
6862 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6863 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6864 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6865 h264_scratch.nFilledLen = 0;
6866 } else {
6867 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
6868 return OMX_ErrorBadParameter;
6869 }
6870 } else {
6871 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
6872 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
6873 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6874 }
6875 /*Push the frame to the Decoder*/
6876 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6877 return OMX_ErrorBadParameter;
6878 }
6879 //frame_count++;
6880 pdest_frame = NULL;
6881 if (m_input_free_q.m_size) {
6882 m_input_free_q.pop_entry(&address,&p2,&id);
6883 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6884 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
6885 pdest_frame->nFilledLen = 0;
6886 pdest_frame->nFlags = 0;
6887 pdest_frame->nTimeStamp = LLONG_MAX;
6888 }
6889 }
6890 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006891 }
Arun Menon906de572013-06-18 17:01:40 -07006892 } else {
6893 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
6894 /*Check if Destination Buffer is full*/
6895 if (h264_scratch.nAllocLen ==
6896 h264_scratch.nFilledLen + h264_scratch.nOffset) {
6897 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
6898 return OMX_ErrorStreamCorrupt;
6899 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006900 }
Arun Menon906de572013-06-18 17:01:40 -07006901
6902 if (!psource_frame->nFilledLen) {
6903 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
6904
6905 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6906 if (pdest_frame) {
6907 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
6908 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6909 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07006910 if(pdest_frame->nFilledLen == 0) {
6911 /* No residual frame from before, send whatever
6912 * we have left */
6913 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6914 h264_scratch.pBuffer, h264_scratch.nFilledLen);
6915 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6916 h264_scratch.nFilledLen = 0;
6917 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
6918 } else {
6919 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
6920 if(!isNewFrame) {
6921 /* Have a residual frame, but we know that the
6922 * AU in this frame is belonging to whatever
6923 * frame we had left over. So append it */
6924 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6925 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6926 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6927 h264_scratch.nFilledLen = 0;
6928 pdest_frame->nTimeStamp = h264_last_au_ts;
6929 } else {
6930 /* Completely new frame, let's just push what
6931 * we have now. The resulting EBD would trigger
6932 * another push */
6933 generate_ebd = OMX_FALSE;
6934 pdest_frame->nTimeStamp = h264_last_au_ts;
6935 h264_last_au_ts = h264_scratch.nTimeStamp;
6936 }
6937 }
Arun Menon906de572013-06-18 17:01:40 -07006938 } else {
6939 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
6940 return OMX_ErrorBadParameter;
6941 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07006942
6943 /* Iff we coalesced two buffers, inherit the flags of both bufs */
6944 if(generate_ebd == OMX_TRUE) {
6945 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
6946 }
Arun Menon906de572013-06-18 17:01:40 -07006947
6948 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
6949 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6950 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
6951#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
6952 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
6953 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
6954 if (!VALID_TS(pdest_frame->nTimeStamp))
6955 pdest_frame->nTimeStamp = ts_in_sei;
6956 }
6957#endif
6958 /*Push the frame to the Decoder*/
6959 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6960 return OMX_ErrorBadParameter;
6961 }
6962 frame_count++;
6963 pdest_frame = NULL;
6964 } else {
6965 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
6966 pdest_frame,h264_scratch.nFilledLen);
6967 generate_ebd = OMX_FALSE;
6968 }
6969 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006970 }
Arun Menon906de572013-06-18 17:01:40 -07006971 if (generate_ebd && !psource_frame->nFilledLen) {
6972 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6973 psource_frame = NULL;
6974 if (m_input_pending_q.m_size) {
6975 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6976 m_input_pending_q.pop_entry(&address,&p2,&id);
6977 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6978 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
6979 psource_frame->nFlags,psource_frame->nFilledLen);
6980 }
6981 }
6982 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006983}
6984
6985OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
6986{
6987 OMX_U8 *buf, *pdest;
6988 OMX_U32 partial_frame = 1;
6989 OMX_U32 buf_len, dest_len;
6990
Arun Menon906de572013-06-18 17:01:40 -07006991 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006992 first_frame = 1;
6993 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
Arun Menon906de572013-06-18 17:01:40 -07006994 if (!m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006995 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
6996 buf = psource_frame->pBuffer;
6997 buf_len = psource_frame->nFilledLen;
6998
6999 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007000 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007001 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007002 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007003 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007004 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007005 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7006 return OMX_ErrorStreamCorrupt;
7007 }
Arun Menon906de572013-06-18 17:01:40 -07007008 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007009 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7010 pdest_frame->nOffset;
7011 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007012 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007013
Arun Menon906de572013-06-18 17:01:40 -07007014 if (dest_len < m_vendor_config.nDataSize) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007015 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7016 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007017 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007018 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7019 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7020 }
7021 }
7022 }
7023
Arun Menon906de572013-06-18 17:01:40 -07007024 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007025 case VC1_AP:
7026 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007027 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007028 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7029 return OMX_ErrorBadParameter;
7030 }
Arun Menon906de572013-06-18 17:01:40 -07007031 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007032
7033 case VC1_SP_MP_RCV:
7034 default:
7035 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7036 return OMX_ErrorBadParameter;
7037 }
7038 return OMX_ErrorNone;
7039}
7040
David Ng38e2d232013-03-15 20:05:58 -07007041#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007042bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007043 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007044{
Arun Menon906de572013-06-18 17:01:40 -07007045 struct pmem_allocation allocation;
7046 allocation.size = buffer_size;
7047 allocation.align = clip2(alignment);
7048 if (allocation.align < 4096) {
7049 allocation.align = 4096;
7050 }
7051 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
7052 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7053 allocation.align, allocation.size);
7054 return false;
7055 }
7056 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007057}
David Ng38e2d232013-03-15 20:05:58 -07007058#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007059#ifdef USE_ION
7060int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007061 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7062 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007063{
Arun Menon906de572013-06-18 17:01:40 -07007064 int fd = -EINVAL;
7065 int rc = -EINVAL;
7066 int ion_dev_flag;
7067 struct vdec_ion ion_buf_info;
7068 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7069 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7070 return -EINVAL;
7071 }
7072 ion_dev_flag = O_RDONLY;
7073 fd = open (MEM_DEVICE, ion_dev_flag);
7074 if (fd < 0) {
7075 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7076 return fd;
7077 }
7078 alloc_data->flags = 0;
7079 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7080 alloc_data->flags |= ION_FLAG_CACHED;
7081 }
7082 alloc_data->len = buffer_size;
7083 alloc_data->align = clip2(alignment);
7084 if (alloc_data->align < 4096) {
7085 alloc_data->align = 4096;
7086 }
7087 if ((secure_mode) && (flag & ION_SECURE))
7088 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007089
Arun Menon906de572013-06-18 17:01:40 -07007090 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7091 if (secure_mode)
7092 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7093 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7094 if (rc || !alloc_data->handle) {
7095 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7096 alloc_data->handle = NULL;
7097 close(fd);
7098 fd = -ENOMEM;
7099 return fd;
7100 }
7101 fd_data->handle = alloc_data->handle;
7102 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7103 if (rc) {
7104 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7105 ion_buf_info.ion_alloc_data = *alloc_data;
7106 ion_buf_info.ion_device_fd = fd;
7107 ion_buf_info.fd_ion_data = *fd_data;
7108 free_ion_memory(&ion_buf_info);
7109 fd_data->fd =-1;
7110 close(fd);
7111 fd = -ENOMEM;
7112 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007113
Arun Menon906de572013-06-18 17:01:40 -07007114 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007115}
7116
Arun Menon906de572013-06-18 17:01:40 -07007117void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7118{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007119
Arun Menon906de572013-06-18 17:01:40 -07007120 if (!buf_ion_info) {
7121 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7122 return;
7123 }
7124 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7125 &buf_ion_info->ion_alloc_data.handle)) {
7126 DEBUG_PRINT_ERROR("\n ION: free failed" );
7127 }
7128 close(buf_ion_info->ion_device_fd);
7129 buf_ion_info->ion_device_fd = -1;
7130 buf_ion_info->ion_alloc_data.handle = NULL;
7131 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007132}
7133#endif
7134void omx_vdec::free_output_buffer_header()
7135{
Arun Menon906de572013-06-18 17:01:40 -07007136 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7137 output_use_buffer = false;
7138 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007139
Arun Menon906de572013-06-18 17:01:40 -07007140 if (m_out_mem_ptr) {
7141 free (m_out_mem_ptr);
7142 m_out_mem_ptr = NULL;
7143 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007144
Arun Menon906de572013-06-18 17:01:40 -07007145 if (m_platform_list) {
7146 free(m_platform_list);
7147 m_platform_list = NULL;
7148 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007149
Arun Menon906de572013-06-18 17:01:40 -07007150 if (drv_ctx.ptr_respbuffer) {
7151 free (drv_ctx.ptr_respbuffer);
7152 drv_ctx.ptr_respbuffer = NULL;
7153 }
7154 if (drv_ctx.ptr_outputbuffer) {
7155 free (drv_ctx.ptr_outputbuffer);
7156 drv_ctx.ptr_outputbuffer = NULL;
7157 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007158#ifdef USE_ION
7159 if (drv_ctx.op_buf_ion_info) {
7160 DEBUG_PRINT_LOW("\n Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007161 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007162 drv_ctx.op_buf_ion_info = NULL;
7163 }
7164#endif
7165}
7166
7167void omx_vdec::free_input_buffer_header()
7168{
7169 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007170 if (arbitrary_bytes) {
7171 if (m_frame_parser.mutils) {
7172 DEBUG_PRINT_LOW("\n Free utils parser");
7173 delete (m_frame_parser.mutils);
7174 m_frame_parser.mutils = NULL;
7175 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007176
Arun Menon906de572013-06-18 17:01:40 -07007177 if (m_inp_heap_ptr) {
7178 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7179 free (m_inp_heap_ptr);
7180 m_inp_heap_ptr = NULL;
7181 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007182
Arun Menon906de572013-06-18 17:01:40 -07007183 if (m_phdr_pmem_ptr) {
7184 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7185 free (m_phdr_pmem_ptr);
7186 m_phdr_pmem_ptr = NULL;
7187 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007188 }
Arun Menon906de572013-06-18 17:01:40 -07007189 if (m_inp_mem_ptr) {
7190 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7191 free (m_inp_mem_ptr);
7192 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007193 }
Arun Menon906de572013-06-18 17:01:40 -07007194 if (drv_ctx.ptr_inputbuffer) {
7195 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7196 free (drv_ctx.ptr_inputbuffer);
7197 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007198 }
7199#ifdef USE_ION
7200 if (drv_ctx.ip_buf_ion_info) {
7201 DEBUG_PRINT_LOW("\n Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007202 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007203 drv_ctx.ip_buf_ion_info = NULL;
7204 }
7205#endif
7206}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007207
7208int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007209{
Arun Menon906de572013-06-18 17:01:40 -07007210 enum v4l2_buf_type btype;
7211 int rc = 0;
7212 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007213
Arun Menon906de572013-06-18 17:01:40 -07007214 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7215 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7216 v4l2_port = OUTPUT_PORT;
7217 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7218 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7219 v4l2_port = CAPTURE_PORT;
7220 } else if (port == OMX_ALL) {
7221 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7222 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007223
Arun Menon906de572013-06-18 17:01:40 -07007224 if (!rc_input)
7225 return rc_input;
7226 else
7227 return rc_output;
7228 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007229
Arun Menon906de572013-06-18 17:01:40 -07007230 if (!streaming[v4l2_port]) {
7231 // already streamed off, warn and move on
7232 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7233 " which is already streamed off", v4l2_port);
7234 return 0;
7235 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007236
Arun Menon906de572013-06-18 17:01:40 -07007237 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007238
Arun Menon906de572013-06-18 17:01:40 -07007239 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7240 if (rc) {
7241 /*TODO: How to handle this case */
7242 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
7243 } else {
7244 streaming[v4l2_port] = false;
7245 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007246
Arun Menon906de572013-06-18 17:01:40 -07007247 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007248}
7249
7250OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7251{
Arun Menon906de572013-06-18 17:01:40 -07007252 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7253 struct v4l2_requestbuffers bufreq;
7254 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7255 struct v4l2_format fmt;
7256 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007257 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007258 buffer_prop->actualcount, buffer_prop->buffer_size);
7259 bufreq.memory = V4L2_MEMORY_USERPTR;
7260 bufreq.count = 1;
7261 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7262 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7263 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7264 fmt.fmt.pix_mp.pixelformat = output_capability;
7265 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7266 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7267 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7268 fmt.fmt.pix_mp.pixelformat = capture_capability;
7269 } else {
7270 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007271 }
Arun Menon906de572013-06-18 17:01:40 -07007272 if (eRet==OMX_ErrorNone) {
7273 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007274 }
Arun Menon906de572013-06-18 17:01:40 -07007275 if (ret) {
7276 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7277 /*TODO: How to handle this case */
7278 eRet = OMX_ErrorInsufficientResources;
7279 return eRet;
7280 } else {
7281 buffer_prop->actualcount = bufreq.count;
7282 buffer_prop->mincount = bufreq.count;
7283 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007284 }
Arun Menon906de572013-06-18 17:01:40 -07007285 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7286 buffer_prop->actualcount, buffer_prop->buffer_size);
7287
7288 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7289 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7290
7291 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7292
7293 update_resolution(fmt.fmt.pix_mp.width,
7294 fmt.fmt.pix_mp.height,
7295 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7296 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7297 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7298 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
7299 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
7300
7301 if (ret) {
7302 /*TODO: How to handle this case */
7303 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7304 eRet = OMX_ErrorInsufficientResources;
7305 } else {
7306 int extra_idx = 0;
7307
7308 eRet = is_video_session_supported();
7309 if (eRet)
7310 return eRet;
7311
7312 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7313 buf_size = buffer_prop->buffer_size;
7314 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7315 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7316 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7317 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7318 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7319 return OMX_ErrorBadParameter;
7320 }
7321 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7322 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7323 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7324 }
7325 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7326 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7327 }
7328 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7329 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7330 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7331 client_extra_data_size);
7332 }
7333 if (client_extra_data_size) {
7334 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7335 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7336 }
7337 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7338 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7339 drv_ctx.extradata_info.buffer_size = extra_data_size;
7340 buf_size += client_extra_data_size;
7341 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7342 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7343 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7344 if (in_reconfig) // BufReq will be set to driver when port is disabled
7345 buffer_prop->buffer_size = buf_size;
7346 else if (buf_size != buffer_prop->buffer_size) {
7347 buffer_prop->buffer_size = buf_size;
7348 eRet = set_buffer_req(buffer_prop);
7349 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007350 }
Arun Menon906de572013-06-18 17:01:40 -07007351 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7352 buffer_prop->actualcount, buffer_prop->buffer_size);
7353 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007354}
7355
7356OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7357{
Arun Menon906de572013-06-18 17:01:40 -07007358 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7359 unsigned buf_size = 0;
7360 struct v4l2_format fmt;
7361 struct v4l2_requestbuffers bufreq;
7362 int ret;
7363 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7364 buffer_prop->actualcount, buffer_prop->buffer_size);
7365 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7366 if (buf_size != buffer_prop->buffer_size) {
7367 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7368 buffer_prop->buffer_size, buf_size);
7369 eRet = OMX_ErrorBadParameter;
7370 } else {
7371 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7372 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007373
Arun Menon906de572013-06-18 17:01:40 -07007374 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7375 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7376 fmt.fmt.pix_mp.pixelformat = output_capability;
7377 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7378 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7379 fmt.fmt.pix_mp.pixelformat = capture_capability;
7380 } else {
7381 eRet = OMX_ErrorBadParameter;
7382 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007383
Arun Menon906de572013-06-18 17:01:40 -07007384 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7385 if (ret) {
7386 /*TODO: How to handle this case */
7387 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7388 eRet = OMX_ErrorInsufficientResources;
7389 }
7390
7391 bufreq.memory = V4L2_MEMORY_USERPTR;
7392 bufreq.count = buffer_prop->actualcount;
7393 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7394 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7395 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7396 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7397 } else {
7398 eRet = OMX_ErrorBadParameter;
7399 }
7400
7401 if (eRet==OMX_ErrorNone) {
7402 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7403 }
7404
7405 if (ret) {
7406 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7407 /*TODO: How to handle this case */
7408 eRet = OMX_ErrorInsufficientResources;
7409 } else if (bufreq.count < buffer_prop->actualcount) {
7410 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7411 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7412 buffer_prop->actualcount, bufreq.count);
7413 eRet = OMX_ErrorInsufficientResources;
7414 } else {
7415 if (!client_buffers.update_buffer_req()) {
7416 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7417 eRet = OMX_ErrorInsufficientResources;
7418 }
7419 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007420 }
Arun Menon906de572013-06-18 17:01:40 -07007421 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007422}
7423
Shalaj Jain273b3e02012-06-22 19:08:03 -07007424OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7425{
Arun Menon906de572013-06-18 17:01:40 -07007426 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7427 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007428}
7429
7430OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7431{
Arun Menon906de572013-06-18 17:01:40 -07007432 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7433 if (!portDefn) {
7434 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007435 }
Arun Menon906de572013-06-18 17:01:40 -07007436 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
7437 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7438 portDefn->nSize = sizeof(portDefn);
7439 portDefn->eDomain = OMX_PortDomainVideo;
7440 if (drv_ctx.frame_rate.fps_denominator > 0)
7441 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7442 drv_ctx.frame_rate.fps_denominator;
7443 else {
7444 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7445 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007446 }
Arun Menon906de572013-06-18 17:01:40 -07007447 if (0 == portDefn->nPortIndex) {
7448 portDefn->eDir = OMX_DirInput;
7449 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7450 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7451 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7452 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7453 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7454 portDefn->bEnabled = m_inp_bEnabled;
7455 portDefn->bPopulated = m_inp_bPopulated;
7456 } else if (1 == portDefn->nPortIndex) {
7457 unsigned int buf_size = 0;
7458 if (!client_buffers.update_buffer_req()) {
7459 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
7460 return OMX_ErrorHardware;
7461 }
7462 if (!client_buffers.get_buffer_req(buf_size)) {
7463 DEBUG_PRINT_ERROR("\n update buffer requirements");
7464 return OMX_ErrorHardware;
7465 }
7466 portDefn->nBufferSize = buf_size;
7467 portDefn->eDir = OMX_DirOutput;
7468 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7469 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7470 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7471 portDefn->bEnabled = m_out_bEnabled;
7472 portDefn->bPopulated = m_out_bPopulated;
7473 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
7474 DEBUG_PRINT_ERROR("\n Error in getting color format");
7475 return OMX_ErrorHardware;
7476 }
7477 } else {
7478 portDefn->eDir = OMX_DirMax;
7479 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7480 (int)portDefn->nPortIndex);
7481 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007482 }
Arun Menon906de572013-06-18 17:01:40 -07007483 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7484 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7485 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7486 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7487 DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
7488 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
7489 portDefn->format.video.nFrameHeight,
7490 portDefn->format.video.nStride,
7491 portDefn->format.video.nSliceHeight);
7492 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007493
7494}
7495
7496OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7497{
Arun Menon906de572013-06-18 17:01:40 -07007498 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7499 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7500 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007501
Arun Menon906de572013-06-18 17:01:40 -07007502 if (!m_out_mem_ptr) {
7503 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
7504 int nBufHdrSize = 0;
7505 int nPlatformEntrySize = 0;
7506 int nPlatformListSize = 0;
7507 int nPMEMInfoSize = 0;
7508 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7509 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7510 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007511
Arun Menon906de572013-06-18 17:01:40 -07007512 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
7513 drv_ctx.op_buf.actualcount);
7514 nBufHdrSize = drv_ctx.op_buf.actualcount *
7515 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007516
Arun Menon906de572013-06-18 17:01:40 -07007517 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7518 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7519 nPlatformListSize = drv_ctx.op_buf.actualcount *
7520 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7521 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7522 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007523
Arun Menon906de572013-06-18 17:01:40 -07007524 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
7525 sizeof(OMX_BUFFERHEADERTYPE),
7526 nPMEMInfoSize,
7527 nPlatformListSize);
7528 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
7529 m_out_bm_count);
7530 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7531 // Alloc mem for platform specific info
7532 char *pPtr=NULL;
7533 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7534 nPMEMInfoSize,1);
7535 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7536 calloc (sizeof(struct vdec_bufferpayload),
7537 drv_ctx.op_buf.actualcount);
7538 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7539 calloc (sizeof (struct vdec_output_frameinfo),
7540 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007541#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007542 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7543 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007544#endif
7545
Arun Menon906de572013-06-18 17:01:40 -07007546 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7547 && drv_ctx.ptr_respbuffer) {
7548 bufHdr = m_out_mem_ptr;
7549 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7550 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7551 (((char *) m_platform_list) + nPlatformListSize);
7552 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7553 (((char *) m_platform_entry) + nPlatformEntrySize);
7554 pPlatformList = m_platform_list;
7555 pPlatformEntry = m_platform_entry;
7556 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007557
Arun Menon906de572013-06-18 17:01:40 -07007558 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007559
Arun Menon906de572013-06-18 17:01:40 -07007560 // Settting the entire storage nicely
7561 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
7562 m_out_mem_ptr,pPlatformEntry);
7563 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
7564 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7565 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7566 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7567 // Set the values when we determine the right HxW param
7568 bufHdr->nAllocLen = 0;
7569 bufHdr->nFilledLen = 0;
7570 bufHdr->pAppPrivate = NULL;
7571 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7572 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7573 pPlatformEntry->entry = pPMEMInfo;
7574 // Initialize the Platform List
7575 pPlatformList->nEntries = 1;
7576 pPlatformList->entryList = pPlatformEntry;
7577 // Keep pBuffer NULL till vdec is opened
7578 bufHdr->pBuffer = NULL;
7579 pPMEMInfo->offset = 0;
7580 pPMEMInfo->pmem_fd = 0;
7581 bufHdr->pPlatformPrivate = pPlatformList;
7582 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007583#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007584 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007585#endif
Arun Menon906de572013-06-18 17:01:40 -07007586 /*Create a mapping between buffers*/
7587 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7588 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7589 &drv_ctx.ptr_outputbuffer[i];
7590 // Move the buffer and buffer header pointers
7591 bufHdr++;
7592 pPMEMInfo++;
7593 pPlatformEntry++;
7594 pPlatformList++;
7595 }
7596 } else {
7597 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
7598 m_out_mem_ptr, pPtr);
7599 if (m_out_mem_ptr) {
7600 free(m_out_mem_ptr);
7601 m_out_mem_ptr = NULL;
7602 }
7603 if (pPtr) {
7604 free(pPtr);
7605 pPtr = NULL;
7606 }
7607 if (drv_ctx.ptr_outputbuffer) {
7608 free(drv_ctx.ptr_outputbuffer);
7609 drv_ctx.ptr_outputbuffer = NULL;
7610 }
7611 if (drv_ctx.ptr_respbuffer) {
7612 free(drv_ctx.ptr_respbuffer);
7613 drv_ctx.ptr_respbuffer = NULL;
7614 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007615#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007616 if (drv_ctx.op_buf_ion_info) {
7617 DEBUG_PRINT_LOW("\n Free o/p ion context");
7618 free(drv_ctx.op_buf_ion_info);
7619 drv_ctx.op_buf_ion_info = NULL;
7620 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007621#endif
Arun Menon906de572013-06-18 17:01:40 -07007622 eRet = OMX_ErrorInsufficientResources;
7623 }
7624 } else {
7625 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007626 }
Arun Menon906de572013-06-18 17:01:40 -07007627 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007628}
7629
7630void omx_vdec::complete_pending_buffer_done_cbs()
7631{
Arun Menon906de572013-06-18 17:01:40 -07007632 unsigned p1;
7633 unsigned p2;
7634 unsigned ident;
7635 omx_cmd_queue tmp_q, pending_bd_q;
7636 pthread_mutex_lock(&m_lock);
7637 // pop all pending GENERATE FDB from ftb queue
7638 while (m_ftb_q.m_size) {
7639 m_ftb_q.pop_entry(&p1,&p2,&ident);
7640 if (ident == OMX_COMPONENT_GENERATE_FBD) {
7641 pending_bd_q.insert_entry(p1,p2,ident);
7642 } else {
7643 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007644 }
Arun Menon906de572013-06-18 17:01:40 -07007645 }
7646 //return all non GENERATE FDB to ftb queue
7647 while (tmp_q.m_size) {
7648 tmp_q.pop_entry(&p1,&p2,&ident);
7649 m_ftb_q.insert_entry(p1,p2,ident);
7650 }
7651 // pop all pending GENERATE EDB from etb queue
7652 while (m_etb_q.m_size) {
7653 m_etb_q.pop_entry(&p1,&p2,&ident);
7654 if (ident == OMX_COMPONENT_GENERATE_EBD) {
7655 pending_bd_q.insert_entry(p1,p2,ident);
7656 } else {
7657 tmp_q.insert_entry(p1,p2,ident);
7658 }
7659 }
7660 //return all non GENERATE FDB to etb queue
7661 while (tmp_q.m_size) {
7662 tmp_q.pop_entry(&p1,&p2,&ident);
7663 m_etb_q.insert_entry(p1,p2,ident);
7664 }
7665 pthread_mutex_unlock(&m_lock);
7666 // process all pending buffer dones
7667 while (pending_bd_q.m_size) {
7668 pending_bd_q.pop_entry(&p1,&p2,&ident);
7669 switch (ident) {
7670 case OMX_COMPONENT_GENERATE_EBD:
7671 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
7672 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
7673 omx_report_error ();
7674 }
7675 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007676
Arun Menon906de572013-06-18 17:01:40 -07007677 case OMX_COMPONENT_GENERATE_FBD:
7678 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
7679 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
7680 omx_report_error ();
7681 }
7682 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007683 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007684 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007685}
7686
7687void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
7688{
Arun Menon906de572013-06-18 17:01:40 -07007689 OMX_U32 new_frame_interval = 0;
7690 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
7691 && llabs(act_timestamp - prev_ts) > 2000) {
7692 new_frame_interval = client_set_fps ? frm_int :
7693 llabs(act_timestamp - prev_ts);
7694 if (new_frame_interval < frm_int || frm_int == 0) {
7695 frm_int = new_frame_interval;
7696 if (frm_int) {
7697 drv_ctx.frame_rate.fps_numerator = 1e6;
7698 drv_ctx.frame_rate.fps_denominator = frm_int;
7699 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
7700 frm_int, drv_ctx.frame_rate.fps_numerator /
7701 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007702
Arun Menon906de572013-06-18 17:01:40 -07007703 /* We need to report the difference between this FBD and the previous FBD
7704 * back to the driver for clock scaling purposes. */
7705 struct v4l2_outputparm oparm;
7706 /*XXX: we're providing timing info as seconds per frame rather than frames
7707 * per second.*/
7708 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
7709 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007710
Arun Menon906de572013-06-18 17:01:40 -07007711 struct v4l2_streamparm sparm;
7712 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7713 sparm.parm.output = oparm;
7714 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
7715 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
7716 performance might be affected");
7717 }
7718
7719 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007720 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007721 }
Arun Menon906de572013-06-18 17:01:40 -07007722 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007723}
7724
7725void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
7726{
Arun Menon906de572013-06-18 17:01:40 -07007727 if (rst_prev_ts && VALID_TS(act_timestamp)) {
7728 prev_ts = act_timestamp;
7729 rst_prev_ts = false;
7730 } else if (VALID_TS(prev_ts)) {
7731 bool codec_cond = (drv_ctx.timestamp_adjust)?
7732 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
7733 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
7734 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
7735 if (frm_int > 0 && codec_cond) {
7736 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
7737 act_timestamp = prev_ts + frm_int;
7738 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
7739 prev_ts = act_timestamp;
7740 } else
7741 set_frame_rate(act_timestamp);
7742 } else if (frm_int > 0) // In this case the frame rate was set along
7743 { // with the port definition, start ts with 0
7744 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
7745 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007746 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007747}
7748
7749void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
7750{
Arun Menon906de572013-06-18 17:01:40 -07007751 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
7752 OMX_U32 num_conceal_MB = 0;
7753 OMX_U32 frame_rate = 0;
7754 int consumed_len = 0;
7755 OMX_U32 num_MB_in_frame;
7756 OMX_U32 recovery_sei_flags = 1;
7757 int enable = 0;
7758 OMX_U32 mbaff = 0;
7759 int buf_index = p_buf_hdr - m_out_mem_ptr;
7760 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
7761 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
7762 p_buf_hdr->nOffset;
7763 if (!drv_ctx.extradata_info.uaddr) {
7764 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007765 }
Arun Menon906de572013-06-18 17:01:40 -07007766 p_extra = (OMX_OTHER_EXTRADATATYPE *)
7767 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
7768 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
7769 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
7770 p_extra = NULL;
7771 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
7772 if (data) {
7773 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
7774 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
7775 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
7776 DEBUG_PRINT_LOW("Invalid extra data size");
7777 break;
7778 }
7779 switch ((unsigned long)data->eType) {
7780 case EXTRADATA_INTERLACE_VIDEO:
7781 struct msm_vidc_interlace_payload *payload;
7782 payload = (struct msm_vidc_interlace_payload *)data->data;
7783 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
7784 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
7785 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
7786 else {
7787 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
7788 enable = 1;
7789 }
7790 if (m_enable_android_native_buffers)
7791 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
7792 PP_PARAM_INTERLACED, (void*)&enable);
7793 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
7794 append_interlace_extradata(p_extra, payload->format);
7795 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
7796 }
7797 break;
7798 case EXTRADATA_FRAME_RATE:
7799 struct msm_vidc_framerate_payload *frame_rate_payload;
7800 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
7801 frame_rate = frame_rate_payload->frame_rate;
7802 break;
7803 case EXTRADATA_TIMESTAMP:
7804 struct msm_vidc_ts_payload *time_stamp_payload;
7805 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
7806 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
7807 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
7808 break;
7809 case EXTRADATA_NUM_CONCEALED_MB:
7810 struct msm_vidc_concealmb_payload *conceal_mb_payload;
7811 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
7812 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
7813 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
7814 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
7815 break;
7816 case EXTRADATA_INDEX:
7817 int *etype;
7818 etype = (int *)(data->data);
7819 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
7820 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
7821 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
7822 if (aspect_ratio_payload) {
7823 ((struct vdec_output_frameinfo *)
7824 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
7825 ((struct vdec_output_frameinfo *)
7826 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
7827 }
7828 }
7829 break;
7830 case EXTRADATA_RECOVERY_POINT_SEI:
7831 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
7832 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
7833 recovery_sei_flags = recovery_sei_payload->flags;
7834 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
7835 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
7836 DEBUG_PRINT_HIGH("\n");
7837 DEBUG_PRINT_HIGH("***************************************************\n");
7838 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
7839 DEBUG_PRINT_HIGH("***************************************************\n");
7840 }
7841 break;
7842 case EXTRADATA_PANSCAN_WINDOW:
7843 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
7844 break;
7845 case EXTRADATA_MPEG2_SEQDISP:
7846 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
7847 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
7848 if (seqdisp_payload) {
7849 m_disp_hor_size = seqdisp_payload->disp_width;
7850 m_disp_vert_size = seqdisp_payload->disp_height;
7851 }
7852 break;
7853 default:
7854 goto unrecognized_extradata;
7855 }
7856 consumed_len += data->nSize;
7857 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
7858 }
7859 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
7860 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
7861 append_frame_info_extradata(p_extra,
7862 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
7863 panscan_payload,&((struct vdec_output_frameinfo *)
7864 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
7865 }
7866 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007867unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07007868 if (!secure_mode && client_extradata)
7869 append_terminator_extradata(p_extra);
7870 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007871}
7872
Vinay Kalia9c00cae2012-12-06 16:08:20 -08007873OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07007874 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007875{
Arun Menon906de572013-06-18 17:01:40 -07007876 OMX_ERRORTYPE ret = OMX_ErrorNone;
7877 struct v4l2_control control;
7878 if (m_state != OMX_StateLoaded) {
7879 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
7880 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08007881 }
Arun Menon906de572013-06-18 17:01:40 -07007882 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
7883 client_extradata, requested_extradata, enable, is_internal);
7884
7885 if (!is_internal) {
7886 if (enable)
7887 client_extradata |= requested_extradata;
7888 else
7889 client_extradata = client_extradata & ~requested_extradata;
7890 }
7891
7892 if (enable) {
7893 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
7894 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7895 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
7896 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7897 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
7898 " Quality of interlaced clips might be impacted.\n");
7899 }
7900 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
7901 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7902 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
7903 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7904 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
7905 }
7906 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7907 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
7908 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7909 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
7910 }
7911 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7912 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
7913 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7914 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
7915 }
7916 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7917 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
7918 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7919 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7920 }
7921 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7922 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
7923 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7924 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7925 }
7926 if (output_capability == V4L2_PIX_FMT_MPEG2) {
7927 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7928 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
7929 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7930 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
7931 }
7932 }
7933 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
7934 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
7935 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
7936 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
7937 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
7938 }
7939 }
7940 }
7941 ret = get_buffer_req(&drv_ctx.op_buf);
7942 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007943}
7944
7945OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
7946{
Arun Menon906de572013-06-18 17:01:40 -07007947 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
7948 OMX_U8 *data_ptr = extra->data, data = 0;
7949 while (byte_count < extra->nDataSize) {
7950 data = *data_ptr;
7951 while (data) {
7952 num_MB += (data&0x01);
7953 data >>= 1;
7954 }
7955 data_ptr++;
7956 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007957 }
Arun Menon906de572013-06-18 17:01:40 -07007958 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
7959 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
7960 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007961}
7962
7963void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
7964{
Arun Menon906de572013-06-18 17:01:40 -07007965 if (!m_debug_extradata)
7966 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007967
7968 DEBUG_PRINT_HIGH(
Arun Menon906de572013-06-18 17:01:40 -07007969 "============== Extra Data ==============\n"
7970 " Size: %lu \n"
7971 " Version: %lu \n"
7972 " PortIndex: %lu \n"
7973 " Type: %x \n"
7974 " DataSize: %lu \n",
7975 extra->nSize, extra->nVersion.nVersion,
7976 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007977
Arun Menon906de572013-06-18 17:01:40 -07007978 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
7979 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
7980 DEBUG_PRINT_HIGH(
7981 "------ Interlace Format ------\n"
7982 " Size: %lu \n"
7983 " Version: %lu \n"
7984 " PortIndex: %lu \n"
7985 " Is Interlace Format: %d \n"
7986 " Interlace Formats: %lu \n"
7987 "=========== End of Interlace ===========\n",
7988 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
7989 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
7990 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
7991 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
7992
7993 DEBUG_PRINT_HIGH(
7994 "-------- Frame Format --------\n"
7995 " Picture Type: %d \n"
7996 " Interlace Type: %d \n"
7997 " Pan Scan Total Frame Num: %lu \n"
7998 " Concealed Macro Blocks: %lu \n"
7999 " frame rate: %lu \n"
8000 " Aspect Ratio X: %lu \n"
8001 " Aspect Ratio Y: %lu \n",
8002 fminfo->ePicType,
8003 fminfo->interlaceType,
8004 fminfo->panScan.numWindows,
8005 fminfo->nConcealedMacroblocks,
8006 fminfo->nFrameRate,
8007 fminfo->aspectRatio.aspectRatioX,
8008 fminfo->aspectRatio.aspectRatioY);
8009
8010 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8011 DEBUG_PRINT_HIGH(
8012 "------------------------------\n"
8013 " Pan Scan Frame Num: %lu \n"
8014 " Rectangle x: %ld \n"
8015 " Rectangle y: %ld \n"
8016 " Rectangle dx: %ld \n"
8017 " Rectangle dy: %ld \n",
8018 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8019 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8020 }
8021
8022 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8023 } else if (extra->eType == OMX_ExtraDataNone) {
8024 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8025 } else {
8026 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008027 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008028}
8029
8030void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008031 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008032{
Arun Menon906de572013-06-18 17:01:40 -07008033 OMX_STREAMINTERLACEFORMAT *interlace_format;
8034 OMX_U32 mbaff = 0;
8035 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8036 return;
8037 }
8038 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8039 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8040 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8041 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8042 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8043 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8044 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8045 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8046 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8047 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8048 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8049 interlace_format->bInterlaceFormat = OMX_FALSE;
8050 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8051 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8052 } else {
8053 interlace_format->bInterlaceFormat = OMX_TRUE;
8054 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8055 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8056 }
8057 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008058}
8059
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008060void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008061 struct vdec_aspectratioinfo *aspect_ratio_info,
8062 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008063{
Arun Menon906de572013-06-18 17:01:40 -07008064 m_extradata = frame_info;
8065 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8066 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
8067 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
8068 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008069}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008070
8071void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008072 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008073 struct msm_vidc_panscan_window_payload *panscan_payload,
8074 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008075{
Arun Menon906de572013-06-18 17:01:40 -07008076 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8077 struct msm_vidc_panscan_window *panscan_window;
8078 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008079 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008080 }
Arun Menon906de572013-06-18 17:01:40 -07008081 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8082 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8083 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8084 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8085 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8086 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8087 switch (picture_type) {
8088 case PICTURE_TYPE_I:
8089 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8090 break;
8091 case PICTURE_TYPE_P:
8092 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8093 break;
8094 case PICTURE_TYPE_B:
8095 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8096 break;
8097 default:
8098 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8099 }
8100 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8101 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8102 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8103 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8104 else
8105 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8106 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8107 frame_info->nConcealedMacroblocks = num_conceal_mb;
8108 frame_info->nFrameRate = frame_rate;
8109 frame_info->panScan.numWindows = 0;
8110 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8111 if (m_disp_hor_size && m_disp_vert_size) {
8112 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8113 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8114 }
8115 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008116
Arun Menon906de572013-06-18 17:01:40 -07008117 if (panscan_payload) {
8118 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8119 panscan_window = &panscan_payload->wnd[0];
8120 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8121 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8122 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8123 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8124 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8125 panscan_window++;
8126 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008127 }
Arun Menon906de572013-06-18 17:01:40 -07008128 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8129 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008130}
8131
8132void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8133{
Arun Menon906de572013-06-18 17:01:40 -07008134 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8135 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8136 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8137 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8138 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8139 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8140 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8141 *portDefn = m_port_def;
8142 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8143 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
8144 portDefn->format.video.nFrameWidth,
8145 portDefn->format.video.nStride,
8146 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008147}
8148
8149void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8150{
Arun Menon906de572013-06-18 17:01:40 -07008151 if (!client_extradata) {
8152 return;
8153 }
8154 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8155 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8156 extra->eType = OMX_ExtraDataNone;
8157 extra->nDataSize = 0;
8158 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008159
Arun Menon906de572013-06-18 17:01:40 -07008160 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008161}
8162
8163OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8164{
Arun Menon906de572013-06-18 17:01:40 -07008165 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8166 if (index >= drv_ctx.ip_buf.actualcount) {
8167 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8168 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008169 }
Arun Menon906de572013-06-18 17:01:40 -07008170 if (m_desc_buffer_ptr == NULL) {
8171 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8172 calloc( (sizeof(desc_buffer_hdr)),
8173 drv_ctx.ip_buf.actualcount);
8174 if (m_desc_buffer_ptr == NULL) {
8175 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8176 return OMX_ErrorInsufficientResources;
8177 }
8178 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008179
Arun Menon906de572013-06-18 17:01:40 -07008180 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8181 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
8182 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8183 return OMX_ErrorInsufficientResources;
8184 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008185
Arun Menon906de572013-06-18 17:01:40 -07008186 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008187}
8188
8189void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8190{
Arun Menon906de572013-06-18 17:01:40 -07008191 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8192 if (m_demux_entries < 8192) {
8193 m_demux_offsets[m_demux_entries++] = address_offset;
8194 }
8195 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008196}
8197
8198void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8199{
Arun Menon906de572013-06-18 17:01:40 -07008200 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8201 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8202 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008203
Arun Menon906de572013-06-18 17:01:40 -07008204 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008205
Arun Menon906de572013-06-18 17:01:40 -07008206 while (index < bytes_to_parse) {
8207 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8208 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8209 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8210 (buf[index+2] == 0x01)) ) {
8211 //Found start code, insert address offset
8212 insert_demux_addr_offset(index);
8213 if (buf[index+2] == 0x01) // 3 byte start code
8214 index += 3;
8215 else //4 byte start code
8216 index += 4;
8217 } else
8218 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008219 }
Arun Menon906de572013-06-18 17:01:40 -07008220 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8221 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008222}
8223
8224OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8225{
Arun Menon906de572013-06-18 17:01:40 -07008226 //fix this, handle 3 byte start code, vc1 terminator entry
8227 OMX_U8 *p_demux_data = NULL;
8228 OMX_U32 desc_data = 0;
8229 OMX_U32 start_addr = 0;
8230 OMX_U32 nal_size = 0;
8231 OMX_U32 suffix_byte = 0;
8232 OMX_U32 demux_index = 0;
8233 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008234
Arun Menon906de572013-06-18 17:01:40 -07008235 if (m_desc_buffer_ptr == NULL) {
8236 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8237 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008238 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008239
Arun Menon906de572013-06-18 17:01:40 -07008240 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8241 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8242 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8243 return OMX_ErrorBadParameter;
8244 }
8245
8246 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8247
8248 if ( ((OMX_U8*)p_demux_data == NULL) ||
8249 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8250 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8251 return OMX_ErrorBadParameter;
8252 } else {
8253 for (; demux_index < m_demux_entries; demux_index++) {
8254 desc_data = 0;
8255 start_addr = m_demux_offsets[demux_index];
8256 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8257 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8258 } else {
8259 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8260 }
8261 if (demux_index < (m_demux_entries - 1)) {
8262 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8263 } else {
8264 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8265 }
8266 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8267 (void *)start_addr,
8268 suffix_byte,
8269 nal_size,
8270 demux_index);
8271 desc_data = (start_addr >> 3) << 1;
8272 desc_data |= (start_addr & 7) << 21;
8273 desc_data |= suffix_byte << 24;
8274
8275 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8276 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8277 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8278 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8279
8280 p_demux_data += 16;
8281 }
8282 if (codec_type_parse == CODEC_TYPE_VC1) {
8283 DEBUG_PRINT_LOW("VC1 terminator entry");
8284 desc_data = 0;
8285 desc_data = 0x82 << 24;
8286 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8287 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8288 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8289 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8290 p_demux_data += 16;
8291 m_demux_entries++;
8292 }
8293 //Add zero word to indicate end of descriptors
8294 memset(p_demux_data, 0, sizeof(OMX_U32));
8295
8296 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8297 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8298 }
8299 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8300 m_demux_entries = 0;
8301 DEBUG_PRINT_LOW("Demux table complete!");
8302 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008303}
8304
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008305OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008306{
Arun Menon906de572013-06-18 17:01:40 -07008307 OMX_ERRORTYPE err = OMX_ErrorNone;
8308 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8309 if (iDivXDrmDecrypt) {
8310 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8311 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008312 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008313 delete iDivXDrmDecrypt;
8314 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008315 }
8316 } else {
8317 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
8318 err = OMX_ErrorUndefined;
8319 }
8320 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008321}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008322
Vinay Kaliada4f4422013-01-09 10:45:03 -08008323omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8324{
Arun Menon906de572013-06-18 17:01:40 -07008325 enabled = false;
8326 omx = NULL;
8327 init_members();
8328 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008329}
8330
8331void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8332{
Arun Menon906de572013-06-18 17:01:40 -07008333 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008334}
8335
Arun Menon906de572013-06-18 17:01:40 -07008336void omx_vdec::allocate_color_convert_buf::init_members()
8337{
8338 allocated_count = 0;
8339 buffer_size_req = 0;
8340 buffer_alignment_req = 0;
8341 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8342 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8343 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8344 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008345#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008346 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008347#endif
Arun Menon906de572013-06-18 17:01:40 -07008348 for (int i = 0; i < MAX_COUNT; i++)
8349 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008350}
8351
Arun Menon906de572013-06-18 17:01:40 -07008352omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8353{
8354 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008355}
8356
8357bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8358{
Arun Menon906de572013-06-18 17:01:40 -07008359 bool status = true;
8360 unsigned int src_size = 0, destination_size = 0;
8361 OMX_COLOR_FORMATTYPE drv_color_format;
8362 if (!omx) {
8363 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8364 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008365 }
Arun Menon906de572013-06-18 17:01:40 -07008366 if (!enabled) {
8367 DEBUG_PRINT_HIGH("\n No color conversion required");
8368 return status;
8369 }
8370 pthread_mutex_lock(&omx->c_lock);
8371 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8372 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8373 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
8374 status = false;
8375 goto fail_update_buf_req;
8376 }
8377 c2d.close();
8378 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8379 omx->drv_ctx.video_resolution.frame_width,
8380 NV12_128m,YCbCr420P);
8381 if (status) {
8382 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8383 if (status)
8384 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8385 }
8386 if (status) {
8387 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8388 !destination_size) {
8389 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
8390 "driver size %d destination size %d",
8391 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8392 status = false;
8393 c2d.close();
8394 buffer_size_req = 0;
8395 } else {
8396 buffer_size_req = destination_size;
8397 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8398 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8399 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8400 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8401 }
8402 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008403fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008404 pthread_mutex_unlock(&omx->c_lock);
8405 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008406}
8407
8408bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008409 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008410{
Arun Menon906de572013-06-18 17:01:40 -07008411 bool status = true;
8412 OMX_COLOR_FORMATTYPE drv_color_format;
8413 if (!omx) {
8414 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8415 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008416 }
Arun Menon906de572013-06-18 17:01:40 -07008417 pthread_mutex_lock(&omx->c_lock);
8418 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8419 drv_color_format = (OMX_COLOR_FORMATTYPE)
8420 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8421 else {
8422 DEBUG_PRINT_ERROR("\n Incorrect color format");
8423 status = false;
8424 }
8425 if (status && (drv_color_format != dest_color_format)) {
8426 DEBUG_PRINT_LOW("Enabling C2D\n");
8427 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
8428 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
8429 status = false;
8430 } else {
8431 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8432 if (enabled)
8433 c2d.destroy();
8434 enabled = false;
8435 if (!c2d.init()) {
8436 DEBUG_PRINT_ERROR("\n open failed for c2d");
8437 status = false;
8438 } else
8439 enabled = true;
8440 }
8441 } else {
8442 if (enabled)
8443 c2d.destroy();
8444 enabled = false;
8445 }
8446 pthread_mutex_unlock(&omx->c_lock);
8447 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008448}
8449
8450OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8451{
Arun Menon906de572013-06-18 17:01:40 -07008452 if (!omx) {
8453 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8454 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008455 }
Arun Menon906de572013-06-18 17:01:40 -07008456 if (!enabled)
8457 return omx->m_out_mem_ptr;
8458 return m_out_mem_ptr_client;
8459}
8460
8461 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
8462(OMX_BUFFERHEADERTYPE *bufadd)
8463{
8464 if (!omx) {
8465 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8466 return NULL;
8467 }
8468 if (!enabled)
8469 return bufadd;
8470
8471 unsigned index = 0;
8472 index = bufadd - omx->m_out_mem_ptr;
8473 if (index < omx->drv_ctx.op_buf.actualcount) {
8474 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
8475 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
8476 bool status;
8477 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
8478 pthread_mutex_lock(&omx->c_lock);
8479 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
8480 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
8481 pmem_baseaddress[index], pmem_baseaddress[index]);
8482 pthread_mutex_unlock(&omx->c_lock);
8483 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
8484 if (!status) {
8485 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
8486 m_out_mem_ptr_client[index].nFilledLen = 0;
8487 return &m_out_mem_ptr_client[index];
8488 }
8489 } else
8490 m_out_mem_ptr_client[index].nFilledLen = 0;
8491 return &m_out_mem_ptr_client[index];
8492 }
8493 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
8494 return NULL;
8495}
8496
8497 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
8498(OMX_BUFFERHEADERTYPE *bufadd)
8499{
8500 if (!omx) {
8501 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8502 return NULL;
8503 }
8504 if (!enabled)
8505 return bufadd;
8506 unsigned index = 0;
8507 index = bufadd - m_out_mem_ptr_client;
8508 if (index < omx->drv_ctx.op_buf.actualcount) {
8509 return &omx->m_out_mem_ptr[index];
8510 }
8511 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
8512 return NULL;
8513}
8514 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
8515(unsigned int &buffer_size)
8516{
8517 bool status = true;
8518 pthread_mutex_lock(&omx->c_lock);
8519 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008520 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07008521 else {
8522 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
8523 DEBUG_PRINT_ERROR("\n Get buffer size failed");
8524 status = false;
8525 goto fail_get_buffer_size;
8526 }
8527 }
8528 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
8529 buffer_size = omx->drv_ctx.op_buf.buffer_size;
8530 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8531 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008532fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07008533 pthread_mutex_unlock(&omx->c_lock);
8534 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008535}
8536OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07008537 OMX_BUFFERHEADERTYPE *bufhdr)
8538{
8539 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008540
Arun Menon906de572013-06-18 17:01:40 -07008541 if (!enabled)
8542 return omx->free_output_buffer(bufhdr);
8543 if (enabled && omx->is_component_secure())
8544 return OMX_ErrorNone;
8545 if (!allocated_count || !bufhdr) {
8546 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
8547 return OMX_ErrorBadParameter;
8548 }
8549 index = bufhdr - m_out_mem_ptr_client;
8550 if (index >= omx->drv_ctx.op_buf.actualcount) {
8551 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
8552 return OMX_ErrorBadParameter;
8553 }
8554 if (pmem_fd[index] > 0) {
8555 munmap(pmem_baseaddress[index], buffer_size_req);
8556 close(pmem_fd[index]);
8557 }
8558 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008559#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008560 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008561#endif
Arun Menon906de572013-06-18 17:01:40 -07008562 m_heap_ptr[index].video_heap_ptr = NULL;
8563 if (allocated_count > 0)
8564 allocated_count--;
8565 else
8566 allocated_count = 0;
8567 if (!allocated_count) {
8568 pthread_mutex_lock(&omx->c_lock);
8569 c2d.close();
8570 init_members();
8571 pthread_mutex_unlock(&omx->c_lock);
8572 }
8573 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008574}
8575
8576OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07008577 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008578{
Arun Menon906de572013-06-18 17:01:40 -07008579 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8580 if (!enabled) {
8581 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
8582 return eRet;
8583 }
8584 if (enabled && omx->is_component_secure()) {
8585 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
8586 omx->is_component_secure());
8587 return OMX_ErrorUnsupportedSetting;
8588 }
8589 if (!bufferHdr || bytes > buffer_size_req) {
8590 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
8591 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
8592 buffer_size_req,bytes);
8593 return OMX_ErrorBadParameter;
8594 }
8595 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
8596 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
8597 return OMX_ErrorInsufficientResources;
8598 }
8599 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
8600 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
8601 port,appData,omx->drv_ctx.op_buf.buffer_size);
8602 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
8603 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
8604 return eRet;
8605 }
8606 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
8607 omx->drv_ctx.op_buf.actualcount) {
8608 DEBUG_PRINT_ERROR("\n Invalid header index %d",
8609 (temp_bufferHdr - omx->m_out_mem_ptr));
8610 return OMX_ErrorUndefined;
8611 }
8612 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008613#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008614 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
8615 buffer_size_req,buffer_alignment_req,
8616 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
8617 0);
8618 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
8619 if (op_buf_ion_info[i].ion_device_fd < 0) {
8620 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
8621 return OMX_ErrorInsufficientResources;
8622 }
8623 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
8624 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008625
Arun Menon906de572013-06-18 17:01:40 -07008626 if (pmem_baseaddress[i] == MAP_FAILED) {
8627 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
8628 close(pmem_fd[i]);
8629 omx->free_ion_memory(&op_buf_ion_info[i]);
8630 return OMX_ErrorInsufficientResources;
8631 }
8632 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
8633 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
8634 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008635#endif
Arun Menon906de572013-06-18 17:01:40 -07008636 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
8637 m_pmem_info_client[i].offset = 0;
8638 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
8639 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8640 m_platform_list_client[i].nEntries = 1;
8641 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
8642 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
8643 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
8644 m_out_mem_ptr_client[i].nFilledLen = 0;
8645 m_out_mem_ptr_client[i].nFlags = 0;
8646 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8647 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
8648 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
8649 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
8650 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
8651 m_out_mem_ptr_client[i].pAppPrivate = appData;
8652 *bufferHdr = &m_out_mem_ptr_client[i];
8653 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
8654 allocated_count++;
8655 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008656}
8657
8658bool omx_vdec::is_component_secure()
8659{
Arun Menon906de572013-06-18 17:01:40 -07008660 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008661}
8662
8663bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
8664{
Arun Menon906de572013-06-18 17:01:40 -07008665 bool status = true;
8666 if (!enabled) {
8667 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8668 dest_color_format = (OMX_COLOR_FORMATTYPE)
8669 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8670 else
8671 status = false;
8672 } else {
8673 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8674 status = false;
8675 } else
8676 dest_color_format = OMX_COLOR_FormatYUV420Planar;
8677 }
8678 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008679}