blob: 1c5e1e5e3261b592a356e7f776e5e34686e5b79a [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>
Arun Menonbdb80b02013-08-12 17:45:54 -070052#ifdef META_DATA_MODE_SUPPORTED
53#include <media/hardware/HardwareAPI.h>
54#endif
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080055#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070056
57#ifndef _ANDROID_
58#include <sys/ioctl.h>
59#include <sys/mman.h>
60#endif //_ANDROID_
61
62#ifdef _ANDROID_
63#include <cutils/properties.h>
64#undef USE_EGL_IMAGE_GPU
65#endif
66
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070067#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070068
69#ifdef _ANDROID_
70#include "DivXDrmDecrypt.h"
71#endif //_ANDROID_
72
Arun Menon9af783f2013-10-22 12:57:14 -070073#ifdef META_DATA_MODE_SUPPORTED
74#include "QComOMXMetadata.h"
75#endif
76
Shalaj Jain273b3e02012-06-22 19:08:03 -070077#ifdef USE_EGL_IMAGE_GPU
78#include <EGL/egl.h>
79#include <EGL/eglQCOM.h>
80#define EGL_BUFFER_HANDLE_QCOM 0x4F00
81#define EGL_BUFFER_OFFSET_QCOM 0x4F01
82#endif
Vinay Kalia21649b32013-03-18 17:28:07 -070083
Jayasena Sangaraboina51230642013-08-21 18:02:13 -070084#define BUFFER_LOG_LOC "/data/misc/media"
85
Shalaj Jain273b3e02012-06-22 19:08:03 -070086#ifdef OUTPUT_EXTRADATA_LOG
87FILE *outputExtradataFile;
88char ouputextradatafilename [] = "/data/extradata";
89#endif
90
91#define DEFAULT_FPS 30
92#define MAX_INPUT_ERROR DEFAULT_FPS
93#define MAX_SUPPORTED_FPS 120
94
95#define VC1_SP_MP_START_CODE 0xC5000000
96#define VC1_SP_MP_START_CODE_MASK 0xFF000000
97#define VC1_AP_SEQ_START_CODE 0x0F010000
98#define VC1_STRUCT_C_PROFILE_MASK 0xF0
99#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
100#define VC1_SIMPLE_PROFILE 0
101#define VC1_MAIN_PROFILE 1
102#define VC1_ADVANCE_PROFILE 3
103#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
104#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
105#define VC1_STRUCT_C_LEN 4
106#define VC1_STRUCT_C_POS 8
107#define VC1_STRUCT_A_POS 12
108#define VC1_STRUCT_B_POS 24
109#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700110#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700111
112#define MEM_DEVICE "/dev/ion"
113#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
114
115#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700116extern "C" {
117#include<utils/Log.h>
118}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700119#endif//_ANDROID_
120
Vinay Kalia53fa6832012-10-11 17:55:30 -0700121#define SZ_4K 0x1000
122#define SZ_1M 0x100000
123
Shalaj Jain273b3e02012-06-22 19:08:03 -0700124#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
125#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 -0700126#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
127
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800128#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700129
130int debug_level = PRIO_ERROR;
131
Shalaj Jain273b3e02012-06-22 19:08:03 -0700132void* async_message_thread (void *input)
133{
Arun Menon906de572013-06-18 17:01:40 -0700134 OMX_BUFFERHEADERTYPE *buffer;
135 struct v4l2_plane plane[VIDEO_MAX_PLANES];
136 struct pollfd pfd;
137 struct v4l2_buffer v4l2_buf;
138 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
139 struct v4l2_event dqevent;
140 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
141 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
142 pfd.fd = omx->drv_ctx.video_driver_fd;
143 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
144 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
145 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
146 while (1) {
147 rc = poll(&pfd, 1, POLL_TIMEOUT);
148 if (!rc) {
149 DEBUG_PRINT_ERROR("Poll timedout\n");
150 break;
151 } else if (rc < 0) {
152 DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
153 break;
154 }
155 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
156 struct vdec_msginfo vdec_msg;
157 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
158 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
159 v4l2_buf.length = omx->drv_ctx.num_planes;
160 v4l2_buf.m.planes = plane;
161 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
162 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
163 vdec_msg.status_code=VDEC_S_SUCCESS;
164 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
165 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
166 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
167 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
168 (uint64_t)v4l2_buf.timestamp.tv_usec;
169 if (vdec_msg.msgdata.output_frame.len) {
170 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
171 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
172 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
173 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
174 }
175 if (omx->async_message_process(input,&vdec_msg) < 0) {
176 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
177 break;
178 }
179 }
180 }
181 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
182 struct vdec_msginfo vdec_msg;
183 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
184 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
185 v4l2_buf.length = 1;
186 v4l2_buf.m.planes = plane;
187 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
188 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
189 vdec_msg.status_code=VDEC_S_SUCCESS;
190 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
191 if (omx->async_message_process(input,&vdec_msg) < 0) {
192 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
193 break;
194 }
195 }
196 }
197 if (pfd.revents & POLLPRI) {
198 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
199 if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
200 struct vdec_msginfo vdec_msg;
201 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
202 vdec_msg.status_code=VDEC_S_SUCCESS;
203 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved insufficient\n");
204 if (omx->async_message_process(input,&vdec_msg) < 0) {
205 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
206 break;
207 }
208 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
209 struct vdec_msginfo vdec_msg;
210 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
211 vdec_msg.status_code=VDEC_S_SUCCESS;
212 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved \n");
213 if (omx->async_message_process(input,&vdec_msg) < 0) {
214 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
215 break;
216 }
217 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
218 vdec_msg.status_code=VDEC_S_SUCCESS;
219 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved \n");
220 if (omx->async_message_process(input,&vdec_msg) < 0) {
221 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
222 break;
223 }
224 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
225 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
226 break;
227 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
228 struct vdec_msginfo vdec_msg;
229 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
230 vdec_msg.status_code=VDEC_S_SUCCESS;
231 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
232 if (omx->async_message_process(input,&vdec_msg) < 0) {
233 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
234 break;
235 }
Arun Menonbdb80b02013-08-12 17:45:54 -0700236 }
237#ifdef META_DATA_MODE_SUPPORTED
238 else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
239 unsigned int *ptr = (unsigned int *)dqevent.u.data;
240 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d\n", ptr[0], ptr[1]);
241 omx->buf_ref_remove(ptr[0], ptr[1]);
242 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
243 unsigned int *ptr = (unsigned int *)dqevent.u.data;
244 struct vdec_msginfo vdec_msg;
245
246 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d\n", ptr[0], ptr[1]);
247
248 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
249 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
250 v4l2_buf.length = omx->drv_ctx.num_planes;
251 v4l2_buf.m.planes = plane;
252 v4l2_buf.index = ptr[5];
253 v4l2_buf.flags = 0;
254
255 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
256 vdec_msg.status_code = VDEC_S_SUCCESS;
257 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
258 vdec_msg.msgdata.output_frame.len = 0;
259 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
260 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
261 (uint64_t)ptr[4];
262 if (omx->async_message_process(input,&vdec_msg) < 0) {
263 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
264 break;
265 }
266 }
267#endif
268 else {
Arun Menon906de572013-06-18 17:01:40 -0700269 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
270 continue;
271 }
272 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700273 }
Arun Menon906de572013-06-18 17:01:40 -0700274 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
275 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700276}
277
278void* message_thread(void *input)
279{
Arun Menon906de572013-06-18 17:01:40 -0700280 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
281 unsigned char id;
282 int n;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700283
Arun Menon906de572013-06-18 17:01:40 -0700284 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
285 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
286 while (1) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700287
Arun Menon906de572013-06-18 17:01:40 -0700288 n = read(omx->m_pipe_in, &id, 1);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700289
Arun Menon906de572013-06-18 17:01:40 -0700290 if (0 == n) {
291 break;
292 }
293
294 if (1 == n) {
295 omx->process_event_cb(omx, id);
296 }
297 if ((n < 0) && (errno != EINTR)) {
298 DEBUG_PRINT_LOW("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
299 break;
300 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700301 }
Arun Menon906de572013-06-18 17:01:40 -0700302 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
303 return 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700304}
305
306void post_message(omx_vdec *omx, unsigned char id)
307{
Arun Menon906de572013-06-18 17:01:40 -0700308 int ret_value;
309 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
310 ret_value = write(omx->m_pipe_out, &id, 1);
311 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700312}
313
314// omx_cmd_queue destructor
315omx_vdec::omx_cmd_queue::~omx_cmd_queue()
316{
Arun Menon906de572013-06-18 17:01:40 -0700317 // Nothing to do
Shalaj Jain273b3e02012-06-22 19:08:03 -0700318}
319
320// omx cmd queue constructor
321omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
322{
323 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
324}
325
326// omx cmd queue insert
327bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
328{
Arun Menon906de572013-06-18 17:01:40 -0700329 bool ret = true;
330 if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
331 m_q[m_write].id = id;
332 m_q[m_write].param1 = p1;
333 m_q[m_write].param2 = p2;
334 m_write++;
335 m_size ++;
336 if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
337 m_write = 0;
338 }
339 } else {
340 ret = false;
341 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700342 }
Arun Menon906de572013-06-18 17:01:40 -0700343 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700344}
345
346// omx cmd queue pop
347bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
348{
Arun Menon906de572013-06-18 17:01:40 -0700349 bool ret = true;
350 if (m_size > 0) {
351 *id = m_q[m_read].id;
352 *p1 = m_q[m_read].param1;
353 *p2 = m_q[m_read].param2;
354 // Move the read pointer ahead
355 ++m_read;
356 --m_size;
357 if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
358 m_read = 0;
359 }
360 } else {
361 ret = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700362 }
Arun Menon906de572013-06-18 17:01:40 -0700363 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700364}
365
366// Retrieve the first mesg type in the queue
367unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
368{
369 return m_q[m_read].id;
370}
371
372#ifdef _ANDROID_
373omx_vdec::ts_arr_list::ts_arr_list()
374{
Arun Menon906de572013-06-18 17:01:40 -0700375 //initialize timestamps array
376 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700377}
378omx_vdec::ts_arr_list::~ts_arr_list()
379{
Arun Menon906de572013-06-18 17:01:40 -0700380 //free m_ts_arr_list?
Shalaj Jain273b3e02012-06-22 19:08:03 -0700381}
382
383bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
384{
Arun Menon906de572013-06-18 17:01:40 -0700385 bool ret = true;
386 bool duplicate_ts = false;
387 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700388
Arun Menon906de572013-06-18 17:01:40 -0700389 //insert at the first available empty location
390 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
391 if (!m_ts_arr_list[idx].valid) {
392 //found invalid or empty entry, save timestamp
393 m_ts_arr_list[idx].valid = true;
394 m_ts_arr_list[idx].timestamp = ts;
395 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
396 ts, idx);
397 break;
398 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700399 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700400
Arun Menon906de572013-06-18 17:01:40 -0700401 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
402 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
403 ret = false;
404 }
405 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700406}
407
408bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
409{
Arun Menon906de572013-06-18 17:01:40 -0700410 bool ret = true;
411 int min_idx = -1;
412 OMX_TICKS min_ts = 0;
413 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700414
Arun Menon906de572013-06-18 17:01:40 -0700415 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700416
Arun Menon906de572013-06-18 17:01:40 -0700417 if (m_ts_arr_list[idx].valid) {
418 //found valid entry, save index
419 if (min_idx < 0) {
420 //first valid entry
421 min_ts = m_ts_arr_list[idx].timestamp;
422 min_idx = idx;
423 } else if (m_ts_arr_list[idx].timestamp < min_ts) {
424 min_ts = m_ts_arr_list[idx].timestamp;
425 min_idx = idx;
426 }
427 }
428
Shalaj Jain273b3e02012-06-22 19:08:03 -0700429 }
430
Arun Menon906de572013-06-18 17:01:40 -0700431 if (min_idx < 0) {
432 //no valid entries found
433 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
434 ts = 0;
435 ret = false;
436 } else {
437 ts = m_ts_arr_list[min_idx].timestamp;
438 m_ts_arr_list[min_idx].valid = false;
439 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
440 ts, min_idx);
441 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700442
Arun Menon906de572013-06-18 17:01:40 -0700443 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700444
445}
446
447
448bool omx_vdec::ts_arr_list::reset_ts_list()
449{
Arun Menon906de572013-06-18 17:01:40 -0700450 bool ret = true;
451 int idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700452
Arun Menon906de572013-06-18 17:01:40 -0700453 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
454 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
455 m_ts_arr_list[idx].valid = false;
456 }
457 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700458}
459#endif
460
461// factory function executed by the core to create instances
462void *get_omx_component_factory_fn(void)
463{
Arun Menon906de572013-06-18 17:01:40 -0700464 return (new omx_vdec);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700465}
466
467#ifdef _ANDROID_
468#ifdef USE_ION
469VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
Arun Menon906de572013-06-18 17:01:40 -0700470 struct ion_handle *handle, int ionMapfd)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700471{
Arun Menon906de572013-06-18 17:01:40 -0700472 // ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700473}
474#else
475VideoHeap::VideoHeap(int fd, size_t size, void* base)
476{
477 // dup file descriptor, map once, use pmem
478 init(dup(fd), base, size, 0 , MEM_DEVICE);
479}
480#endif
481#endif // _ANDROID_
482/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700483 FUNCTION
484 omx_vdec::omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700485
Arun Menon906de572013-06-18 17:01:40 -0700486 DESCRIPTION
487 Constructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700488
Arun Menon906de572013-06-18 17:01:40 -0700489 PARAMETERS
490 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700491
Arun Menon906de572013-06-18 17:01:40 -0700492 RETURN VALUE
493 None.
494 ========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800495omx_vdec::omx_vdec(): m_error_propogated(false),
Arun Menon906de572013-06-18 17:01:40 -0700496 m_state(OMX_StateInvalid),
497 m_app_data(NULL),
498 m_inp_mem_ptr(NULL),
499 m_out_mem_ptr(NULL),
500 m_inp_err_count(0),
501 input_flush_progress (false),
502 output_flush_progress (false),
503 input_use_buffer (false),
504 output_use_buffer (false),
505 ouput_egl_buffers(false),
506 m_use_output_pmem(OMX_FALSE),
507 m_out_mem_region_smi(OMX_FALSE),
508 m_out_pvt_entry_pmem(OMX_FALSE),
509 pending_input_buffers(0),
510 pending_output_buffers(0),
511 m_out_bm_count(0),
512 m_inp_bm_count(0),
513 m_inp_bPopulated(OMX_FALSE),
514 m_out_bPopulated(OMX_FALSE),
515 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700516#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700517 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700518#endif
Arun Menon906de572013-06-18 17:01:40 -0700519 m_inp_bEnabled(OMX_TRUE),
520 m_out_bEnabled(OMX_TRUE),
521 m_in_alloc_cnt(0),
522 m_platform_list(NULL),
523 m_platform_entry(NULL),
524 m_pmem_info(NULL),
525 arbitrary_bytes (true),
526 psource_frame (NULL),
527 pdest_frame (NULL),
528 m_inp_heap_ptr (NULL),
529 m_phdr_pmem_ptr(NULL),
530 m_heap_inp_bm_count (0),
531 codec_type_parse ((codec_type)0),
532 first_frame_meta (true),
533 frame_count (0),
534 nal_count (0),
535 nal_length(0),
536 look_ahead_nal (false),
537 first_frame(0),
538 first_buffer(NULL),
539 first_frame_size (0),
540 m_device_file_ptr(NULL),
541 m_vc1_profile((vc1_profile_type)0),
542 m_profile(0),
543 h264_last_au_ts(LLONG_MAX),
544 h264_last_au_flags(0),
545 prev_ts(LLONG_MAX),
546 rst_prev_ts(true),
547 frm_int(0),
548 m_disp_hor_size(0),
549 m_disp_vert_size(0),
550 in_reconfig(false),
551 m_display_id(NULL),
552 h264_parser(NULL),
553 client_extradata(0),
554 m_reject_avc_1080p_mp (0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700555#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700556 m_enable_android_native_buffers(OMX_FALSE),
557 m_use_android_native_buffers(OMX_FALSE),
558 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700559#endif
Arun Menon906de572013-06-18 17:01:40 -0700560 m_desc_buffer_ptr(NULL),
561 secure_mode(false),
562 client_set_fps(false)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700563{
Arun Menon906de572013-06-18 17:01:40 -0700564 /* Assumption is that , to begin with , we have all the frames with decoder */
565 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700566 memset(&m_debug,0,sizeof(m_debug));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700567#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700568 char property_value[PROPERTY_VALUE_MAX] = {0};
Jayasena Sangaraboinac4dfc282013-08-08 12:41:39 -0700569 property_get("vidc.debug.level", property_value, "0");
570 debug_level = atoi(property_value);
571 property_value[0] = '\0';
572
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700573 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
574
Arun Menon906de572013-06-18 17:01:40 -0700575 property_get("vidc.dec.debug.perf", property_value, "0");
576 perf_flag = atoi(property_value);
577 if (perf_flag) {
578 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
579 dec_time.start();
580 proc_frms = latency = 0;
581 }
582 prev_n_filled_len = 0;
583 property_value[0] = '\0';
584 property_get("vidc.dec.debug.ts", property_value, "0");
585 m_debug_timestamp = atoi(property_value);
586 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
587 if (m_debug_timestamp) {
588 time_stamp_dts.set_timestamp_reorder_mode(true);
589 time_stamp_dts.enable_debug_print(true);
590 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700591
Arun Menon906de572013-06-18 17:01:40 -0700592 property_value[0] = '\0';
593 property_get("vidc.dec.debug.concealedmb", property_value, "0");
594 m_debug_concealedmb = atoi(property_value);
595 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700596
Arun Menon906de572013-06-18 17:01:40 -0700597 property_value[0] = '\0';
598 property_get("vidc.dec.profile.check", property_value, "0");
599 m_reject_avc_1080p_mp = atoi(property_value);
600 DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
Rajeshwar Kurapatye0e7d0c2013-07-30 19:46:26 +0530601
Jayasena Sangaraboina51230642013-08-21 18:02:13 -0700602 property_value[0] = '\0';
603 property_get("vidc.dec.log.in", property_value, "0");
604 m_debug.in_buffer_log = atoi(property_value);
605
606 property_value[0] = '\0';
607 property_get("vidc.dec.log.out", property_value, "0");
608 m_debug.out_buffer_log = atoi(property_value);
609 sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
610
611 property_value[0] = '\0';
612 property_get("vidc.log.loc", property_value, "");
613 if (*property_value)
614 strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700615#endif
Arun Menon906de572013-06-18 17:01:40 -0700616 memset(&m_cmp,0,sizeof(m_cmp));
617 memset(&m_cb,0,sizeof(m_cb));
618 memset (&drv_ctx,0,sizeof(drv_ctx));
619 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
620 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
621 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
622 m_demux_entries = 0;
623 msg_thread_id = 0;
624 async_thread_id = 0;
625 msg_thread_created = false;
626 async_thread_created = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700627#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -0700628 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700629#endif
Arun Menon906de572013-06-18 17:01:40 -0700630 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
631 drv_ctx.timestamp_adjust = false;
632 drv_ctx.video_driver_fd = -1;
633 m_vendor_config.pData = NULL;
634 pthread_mutex_init(&m_lock, NULL);
635 pthread_mutex_init(&c_lock, NULL);
636 sem_init(&m_cmd_lock,0,0);
637 streaming[CAPTURE_PORT] =
638 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700639#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -0700640 char extradata_value[PROPERTY_VALUE_MAX] = {0};
641 property_get("vidc.dec.debug.extradata", extradata_value, "0");
642 m_debug_extradata = atoi(extradata_value);
643 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700644#endif
Arun Menon906de572013-06-18 17:01:40 -0700645 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
646 client_buffers.set_vdec_client(this);
Arun Menonbdb80b02013-08-12 17:45:54 -0700647#ifdef META_DATA_MODE_SUPPORTED
648 dynamic_buf_mode = false;
649 out_dynamic_list = NULL;
650#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -0700651}
652
Vinay Kalia85793762012-06-14 19:12:34 -0700653static const int event_type[] = {
Arun Menon906de572013-06-18 17:01:40 -0700654 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
655 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
656 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Arun Menonbdb80b02013-08-12 17:45:54 -0700657#ifdef META_DATA_MODE_SUPPORTED
658 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
659 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
660#endif
Arun Menon906de572013-06-18 17:01:40 -0700661 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
662 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700663};
664
665static OMX_ERRORTYPE subscribe_to_events(int fd)
666{
Arun Menon906de572013-06-18 17:01:40 -0700667 OMX_ERRORTYPE eRet = OMX_ErrorNone;
668 struct v4l2_event_subscription sub;
669 int array_sz = sizeof(event_type)/sizeof(int);
670 int i,rc;
671 if (fd < 0) {
672 printf("Invalid input: %d\n", fd);
673 return OMX_ErrorBadParameter;
674 }
Vinay Kalia85793762012-06-14 19:12:34 -0700675
Arun Menon906de572013-06-18 17:01:40 -0700676 for (i = 0; i < array_sz; ++i) {
677 memset(&sub, 0, sizeof(sub));
678 sub.type = event_type[i];
679 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
680 if (rc) {
681 printf("Failed to subscribe event: 0x%x\n", sub.type);
682 break;
683 }
684 }
685 if (i < array_sz) {
686 for (--i; i >=0 ; i--) {
687 memset(&sub, 0, sizeof(sub));
688 sub.type = event_type[i];
689 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
690 if (rc)
691 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
692 }
693 eRet = OMX_ErrorNotImplemented;
694 }
695 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700696}
697
698
699static OMX_ERRORTYPE unsubscribe_to_events(int fd)
700{
Arun Menon906de572013-06-18 17:01:40 -0700701 OMX_ERRORTYPE eRet = OMX_ErrorNone;
702 struct v4l2_event_subscription sub;
703 int array_sz = sizeof(event_type)/sizeof(int);
704 int i,rc;
705 if (fd < 0) {
706 printf("Invalid input: %d\n", fd);
707 return OMX_ErrorBadParameter;
708 }
Vinay Kalia85793762012-06-14 19:12:34 -0700709
Arun Menon906de572013-06-18 17:01:40 -0700710 for (i = 0; i < array_sz; ++i) {
711 memset(&sub, 0, sizeof(sub));
712 sub.type = event_type[i];
713 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
714 if (rc) {
715 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
716 break;
717 }
718 }
719 return eRet;
Vinay Kalia85793762012-06-14 19:12:34 -0700720}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700721
722/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700723 FUNCTION
724 omx_vdec::~omx_vdec
Shalaj Jain273b3e02012-06-22 19:08:03 -0700725
Arun Menon906de572013-06-18 17:01:40 -0700726 DESCRIPTION
727 Destructor
Shalaj Jain273b3e02012-06-22 19:08:03 -0700728
Arun Menon906de572013-06-18 17:01:40 -0700729 PARAMETERS
730 None
Shalaj Jain273b3e02012-06-22 19:08:03 -0700731
Arun Menon906de572013-06-18 17:01:40 -0700732 RETURN VALUE
733 None.
734 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700735omx_vdec::~omx_vdec()
736{
Arun Menon906de572013-06-18 17:01:40 -0700737 m_pmem_info = NULL;
738 struct v4l2_decoder_cmd dec;
739 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
740 if (m_pipe_in) close(m_pipe_in);
741 if (m_pipe_out) close(m_pipe_out);
742 m_pipe_in = -1;
743 m_pipe_out = -1;
744 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
745 if (msg_thread_created)
746 pthread_join(msg_thread_id,NULL);
747 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
748 dec.cmd = V4L2_DEC_CMD_STOP;
749 if (drv_ctx.video_driver_fd >=0 ) {
750 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
751 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
752 }
753 if (async_thread_created)
754 pthread_join(async_thread_id,NULL);
755 unsubscribe_to_events(drv_ctx.video_driver_fd);
756 close(drv_ctx.video_driver_fd);
757 pthread_mutex_destroy(&m_lock);
758 pthread_mutex_destroy(&c_lock);
759 sem_destroy(&m_cmd_lock);
760 if (perf_flag) {
761 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
762 dec_time.end();
763 }
764 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
Shalaj Jain273b3e02012-06-22 19:08:03 -0700765}
766
Arun Menon906de572013-06-18 17:01:40 -0700767int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
768{
769 struct v4l2_requestbuffers bufreq;
770 int rc = 0;
771 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
772 bufreq.memory = V4L2_MEMORY_USERPTR;
773 bufreq.count = 0;
774 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
775 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Surajit Podder12aefac2013-08-06 18:43:32 +0530776 } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
777 bufreq.memory = V4L2_MEMORY_USERPTR;
778 bufreq.count = 0;
779 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
780 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Arun Menon906de572013-06-18 17:01:40 -0700781 }
782 return rc;
Vinay Kaliafeef7032012-09-25 19:23:33 -0700783}
784
Shalaj Jain273b3e02012-06-22 19:08:03 -0700785/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -0700786 FUNCTION
787 omx_vdec::OMXCntrlProcessMsgCb
Shalaj Jain273b3e02012-06-22 19:08:03 -0700788
Arun Menon906de572013-06-18 17:01:40 -0700789 DESCRIPTION
790 IL Client callbacks are generated through this routine. The decoder
791 provides the thread context for this routine.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700792
Arun Menon906de572013-06-18 17:01:40 -0700793 PARAMETERS
794 ctxt -- Context information related to the self.
795 id -- Event identifier. This could be any of the following:
796 1. Command completion event
797 2. Buffer done callback event
798 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -0700799
Arun Menon906de572013-06-18 17:01:40 -0700800 RETURN VALUE
801 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -0700802
Arun Menon906de572013-06-18 17:01:40 -0700803 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -0700804void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
805{
Arun Menon906de572013-06-18 17:01:40 -0700806 signed p1; // Parameter - 1
807 signed p2; // Parameter - 2
808 unsigned ident;
809 unsigned qsize=0; // qsize
810 omx_vdec *pThis = (omx_vdec *) ctxt;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700811
Arun Menon906de572013-06-18 17:01:40 -0700812 if (!pThis) {
813 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
814 __func__);
815 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700816 }
817
Arun Menon906de572013-06-18 17:01:40 -0700818 // Protect the shared queue data structure
819 do {
820 /*Read the message id's from the queue*/
821 pthread_mutex_lock(&pThis->m_lock);
822 qsize = pThis->m_cmd_q.m_size;
823 if (qsize) {
824 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700825 }
Arun Menon906de572013-06-18 17:01:40 -0700826
827 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
828 qsize = pThis->m_ftb_q.m_size;
829 if (qsize) {
830 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
831 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700832 }
Arun Menon906de572013-06-18 17:01:40 -0700833
834 if (qsize == 0 && pThis->m_state != OMX_StatePause) {
835 qsize = pThis->m_etb_q.m_size;
836 if (qsize) {
837 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
838 }
839 }
840 pthread_mutex_unlock(&pThis->m_lock);
841
842 /*process message if we have one*/
843 if (qsize > 0) {
844 id = ident;
845 switch (id) {
846 case OMX_COMPONENT_GENERATE_EVENT:
847 if (pThis->m_cb.EventHandler) {
848 switch (p1) {
849 case OMX_CommandStateSet:
850 pThis->m_state = (OMX_STATETYPE) p2;
851 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
852 pThis->m_state);
853 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
854 OMX_EventCmdComplete, p1, p2, NULL);
855 break;
856
857 case OMX_EventError:
858 if (p2 == OMX_StateInvalid) {
859 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
860 pThis->m_state = (OMX_STATETYPE) p2;
861 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
862 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
863 } else if (p2 == OMX_ErrorHardware) {
864 pThis->omx_report_error();
865 } else {
866 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
867 OMX_EventError, p2, (OMX_U32)NULL, NULL );
868 }
869 break;
870
871 case OMX_CommandPortDisable:
872 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
873 if (BITMASK_PRESENT(&pThis->m_flags,
874 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
875 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
876 break;
877 }
878 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
879 OMX_ERRORTYPE eRet = OMX_ErrorNone;
880 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
881 if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
882 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
883 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
884 pThis->in_reconfig = false;
885 if (eRet != OMX_ErrorNone) {
886 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
887 pThis->omx_report_error();
888 break;
889 }
890 }
891 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
892 OMX_EventCmdComplete, p1, p2, NULL );
893 break;
894 case OMX_CommandPortEnable:
895 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
896 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
897 OMX_EventCmdComplete, p1, p2, NULL );
898 break;
899
900 default:
901 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
902 OMX_EventCmdComplete, p1, p2, NULL );
903 break;
904
905 }
906 } else {
907 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
908 }
909 break;
910 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
911 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
912 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
913 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
914 pThis->omx_report_error ();
915 }
916 break;
917 case OMX_COMPONENT_GENERATE_ETB:
918 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
919 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
920 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
921 pThis->omx_report_error ();
922 }
923 break;
924
925 case OMX_COMPONENT_GENERATE_FTB:
926 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
927 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
928 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
929 pThis->omx_report_error ();
930 }
931 break;
932
933 case OMX_COMPONENT_GENERATE_COMMAND:
934 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
935 (OMX_U32)p2,(OMX_PTR)NULL);
936 break;
937
938 case OMX_COMPONENT_GENERATE_EBD:
939
940 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
941 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
942 pThis->omx_report_error ();
943 } else {
944 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
945 pThis->m_inp_err_count++;
946 pThis->time_stamp_dts.remove_time_stamp(
947 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
948 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
949 ?true:false);
950 } else {
951 pThis->m_inp_err_count = 0;
952 }
953 if ( pThis->empty_buffer_done(&pThis->m_cmp,
954 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
955 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
956 pThis->omx_report_error ();
957 }
958 if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
959 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
960 pThis->omx_report_error ();
961 }
962 }
963 break;
964 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
965 int64_t *timestamp = (int64_t *)p1;
966 if (p1) {
967 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
968 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
969 ?true:false);
970 free(timestamp);
971 }
972 }
973 break;
974 case OMX_COMPONENT_GENERATE_FBD:
975 if (p2 != VDEC_S_SUCCESS) {
976 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
977 pThis->omx_report_error ();
978 } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
979 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
980 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
981 pThis->omx_report_error ();
982 }
983 break;
984
985 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
986 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
987 if (!pThis->input_flush_progress) {
988 DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
989 } else {
990 pThis->execute_input_flush();
991 if (pThis->m_cb.EventHandler) {
992 if (p2 != VDEC_S_SUCCESS) {
993 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
994 pThis->omx_report_error ();
995 } else {
996 /*Check if we need generate event for Flush done*/
997 if (BITMASK_PRESENT(&pThis->m_flags,
998 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
999 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
1000 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
1001 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1002 OMX_EventCmdComplete,OMX_CommandFlush,
1003 OMX_CORE_INPUT_PORT_INDEX,NULL );
1004 }
1005 if (BITMASK_PRESENT(&pThis->m_flags,
1006 OMX_COMPONENT_IDLE_PENDING)) {
1007 if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
1008 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
1009 pThis->omx_report_error ();
1010 } else {
1011 pThis->streaming[OUTPUT_PORT] = false;
1012 }
1013 if (!pThis->output_flush_progress) {
1014 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
1015 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1016 OMX_COMPONENT_GENERATE_STOP_DONE);
1017 }
1018 }
1019 }
1020 } else {
1021 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1022 }
1023 }
1024 break;
1025
1026 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1027 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
1028 if (!pThis->output_flush_progress) {
1029 DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
1030 } else {
1031 pThis->execute_output_flush();
1032 if (pThis->m_cb.EventHandler) {
1033 if (p2 != VDEC_S_SUCCESS) {
1034 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1035 pThis->omx_report_error ();
1036 } else {
1037 /*Check if we need generate event for Flush done*/
1038 if (BITMASK_PRESENT(&pThis->m_flags,
1039 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
1040 DEBUG_PRINT_LOW("\n Notify Output Flush done");
1041 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1042 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1043 OMX_EventCmdComplete,OMX_CommandFlush,
1044 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1045 }
1046 if (BITMASK_PRESENT(&pThis->m_flags,
1047 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
1048 DEBUG_PRINT_LOW("\n Internal flush complete");
1049 BITMASK_CLEAR (&pThis->m_flags,
1050 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1051 if (BITMASK_PRESENT(&pThis->m_flags,
1052 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
1053 pThis->post_event(OMX_CommandPortDisable,
1054 OMX_CORE_OUTPUT_PORT_INDEX,
1055 OMX_COMPONENT_GENERATE_EVENT);
1056 BITMASK_CLEAR (&pThis->m_flags,
1057 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1058
1059 }
1060 }
1061
1062 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
1063 if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
1064 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1065 pThis->omx_report_error ();
1066 break;
1067 }
1068 pThis->streaming[CAPTURE_PORT] = false;
1069 if (!pThis->input_flush_progress) {
1070 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
1071 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
1072 OMX_COMPONENT_GENERATE_STOP_DONE);
1073 }
1074 }
1075 }
1076 } else {
1077 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1078 }
1079 }
1080 break;
1081
1082 case OMX_COMPONENT_GENERATE_START_DONE:
1083 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1084
1085 if (pThis->m_cb.EventHandler) {
1086 if (p2 != VDEC_S_SUCCESS) {
1087 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1088 pThis->omx_report_error ();
1089 } else {
1090 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1091 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1092 DEBUG_PRINT_LOW("\n Move to executing");
1093 // Send the callback now
1094 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1095 pThis->m_state = OMX_StateExecuting;
1096 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1097 OMX_EventCmdComplete,OMX_CommandStateSet,
1098 OMX_StateExecuting, NULL);
1099 } else if (BITMASK_PRESENT(&pThis->m_flags,
1100 OMX_COMPONENT_PAUSE_PENDING)) {
1101 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1102 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
1103 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1104 pThis->omx_report_error ();
1105 }
1106 }
1107 }
1108 } else {
1109 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1110 }
1111 break;
1112
1113 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1114 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1115 if (pThis->m_cb.EventHandler) {
1116 if (p2 != VDEC_S_SUCCESS) {
1117 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1118 pThis->omx_report_error ();
1119 } else {
1120 pThis->complete_pending_buffer_done_cbs();
1121 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
1122 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1123 //Send the callback now
1124 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1125 pThis->m_state = OMX_StatePause;
1126 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1127 OMX_EventCmdComplete,OMX_CommandStateSet,
1128 OMX_StatePause, NULL);
1129 }
1130 }
1131 } else {
1132 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1133 }
1134
1135 break;
1136
1137 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1138 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1139 if (pThis->m_cb.EventHandler) {
1140 if (p2 != VDEC_S_SUCCESS) {
1141 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1142 pThis->omx_report_error ();
1143 } else {
1144 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1145 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1146 // Send the callback now
1147 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1148 pThis->m_state = OMX_StateExecuting;
1149 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1150 OMX_EventCmdComplete,OMX_CommandStateSet,
1151 OMX_StateExecuting,NULL);
1152 }
1153 }
1154 } else {
1155 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1156 }
1157
1158 break;
1159
1160 case OMX_COMPONENT_GENERATE_STOP_DONE:
1161 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1162 if (pThis->m_cb.EventHandler) {
1163 if (p2 != VDEC_S_SUCCESS) {
1164 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1165 pThis->omx_report_error ();
1166 } else {
1167 pThis->complete_pending_buffer_done_cbs();
1168 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
1169 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1170 // Send the callback now
1171 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1172 pThis->m_state = OMX_StateIdle;
1173 DEBUG_PRINT_LOW("\n Move to Idle State");
1174 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1175 OMX_EventCmdComplete,OMX_CommandStateSet,
1176 OMX_StateIdle,NULL);
1177 }
1178 }
1179 } else {
1180 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1181 }
1182
1183 break;
1184
1185 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1186 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
1187
1188 if (p2 == OMX_IndexParamPortDefinition) {
1189 pThis->in_reconfig = true;
1190 }
1191 if (pThis->m_cb.EventHandler) {
1192 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1193 OMX_EventPortSettingsChanged, p1, p2, NULL );
1194 } else {
1195 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1196 }
1197
Arun Menon906de572013-06-18 17:01:40 -07001198 break;
1199
1200 case OMX_COMPONENT_GENERATE_EOS_DONE:
1201 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1202 if (pThis->m_cb.EventHandler) {
1203 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1204 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1205 } else {
1206 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1207 }
1208 pThis->prev_ts = LLONG_MAX;
1209 pThis->rst_prev_ts = true;
1210 break;
1211
1212 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1213 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1214 pThis->omx_report_error ();
1215 break;
1216
1217 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1218 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
1219 pThis->omx_report_unsupported_setting();
1220 break;
1221
Arun Menon906de572013-06-18 17:01:40 -07001222 default:
1223 break;
1224 }
1225 }
1226 pthread_mutex_lock(&pThis->m_lock);
1227 qsize = pThis->m_cmd_q.m_size;
1228 if (pThis->m_state != OMX_StatePause)
1229 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1230 pthread_mutex_unlock(&pThis->m_lock);
1231 } while (qsize>0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001232
1233}
1234
Vinay Kaliab9e98102013-04-02 19:31:43 -07001235int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
Vinay Kalia592e4b42012-12-19 15:55:47 -08001236{
Arun Menon906de572013-06-18 17:01:40 -07001237 int format_changed = 0;
1238 if ((height != drv_ctx.video_resolution.frame_height) ||
1239 (width != drv_ctx.video_resolution.frame_width)) {
1240 DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)\n",
1241 width, drv_ctx.video_resolution.frame_width,
1242 height,drv_ctx.video_resolution.frame_height);
1243 format_changed = 1;
1244 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001245 drv_ctx.video_resolution.frame_height = height;
1246 drv_ctx.video_resolution.frame_width = width;
Vinay Kalia21649b32013-03-18 17:28:07 -07001247 drv_ctx.video_resolution.scan_lines = scan_lines;
1248 drv_ctx.video_resolution.stride = stride;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001249 rectangle.nLeft = 0;
1250 rectangle.nTop = 0;
1251 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1252 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
Arun Menon906de572013-06-18 17:01:40 -07001253 return format_changed;
Vinay Kalia592e4b42012-12-19 15:55:47 -08001254}
1255
Arun Menon6836ba02013-02-19 20:37:40 -08001256OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1257{
Arun Menon906de572013-06-18 17:01:40 -07001258 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
1259 OMX_MAX_STRINGNAME_SIZE) &&
1260 (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
1261 m_decoder_capability.max_width = 1280;
1262 m_decoder_capability.max_height = 720;
1263 DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
1264 }
Arun Menon888aa852013-05-30 11:24:42 -07001265
Arun Menon906de572013-06-18 17:01:40 -07001266 if ((drv_ctx.video_resolution.frame_width *
1267 drv_ctx.video_resolution.frame_height >
1268 m_decoder_capability.max_width *
1269 m_decoder_capability.max_height) ||
1270 (drv_ctx.video_resolution.frame_width*
1271 drv_ctx.video_resolution.frame_height <
1272 m_decoder_capability.min_width *
1273 m_decoder_capability.min_height)) {
1274 DEBUG_PRINT_ERROR(
1275 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
1276 drv_ctx.video_resolution.frame_width,
1277 drv_ctx.video_resolution.frame_height,
1278 m_decoder_capability.min_width,
1279 m_decoder_capability.min_height,
1280 m_decoder_capability.max_width,
1281 m_decoder_capability.max_height);
1282 return OMX_ErrorUnsupportedSetting;
1283 }
1284 DEBUG_PRINT_HIGH("\n video session supported\n");
1285 return OMX_ErrorNone;
Arun Menon6836ba02013-02-19 20:37:40 -08001286}
1287
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07001288int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
1289{
1290 if (m_debug.in_buffer_log && !m_debug.infile) {
1291 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
1292 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
1293 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1294 }
1295 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
1296 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.mpg", m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); }
1297 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
1298 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
1299 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1300 }
1301 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
1302 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
1303 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1304 }
1305 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
1306 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1307 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1308 }
1309 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
1310 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
1311 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1312 }
1313 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1314 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
1315 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1316 }
1317 m_debug.infile = fopen (m_debug.infile_name, "ab");
1318 if (!m_debug.infile) {
1319 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging\n", m_debug.infile_name);
1320 m_debug.infile_name[0] = '\0';
1321 return -1;
1322 }
1323 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1324 struct ivf_file_header {
1325 OMX_U8 signature[4]; //='DKIF';
1326 OMX_U8 version ; //= 0;
1327 OMX_U8 headersize ; //= 32;
1328 OMX_U32 FourCC;
1329 OMX_U8 width;
1330 OMX_U8 height;
1331 OMX_U32 rate;
1332 OMX_U32 scale;
1333 OMX_U32 length;
1334 OMX_U8 unused[4];
1335 } file_header;
1336
1337 memset((void *)&file_header,0,sizeof(file_header));
1338 file_header.signature[0] = 'D';
1339 file_header.signature[1] = 'K';
1340 file_header.signature[2] = 'I';
1341 file_header.signature[3] = 'F';
1342 file_header.version = 0;
1343 file_header.headersize = 32;
1344 file_header.FourCC = 0x30385056;
1345 fwrite((const char *)&file_header,
1346 sizeof(file_header),1,m_debug.infile);
1347 }
1348 }
1349 if (m_debug.infile && buffer_addr && buffer_len) {
1350 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
1351 struct vp8_ivf_frame_header {
1352 OMX_U32 framesize;
1353 OMX_U32 timestamp_lo;
1354 OMX_U32 timestamp_hi;
1355 } vp8_frame_header;
1356 vp8_frame_header.framesize = buffer_len;
1357 /* Currently FW doesn't use timestamp values */
1358 vp8_frame_header.timestamp_lo = 0;
1359 vp8_frame_header.timestamp_hi = 0;
1360 fwrite((const char *)&vp8_frame_header,
1361 sizeof(vp8_frame_header),1,m_debug.infile);
1362 }
1363 fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
1364 }
1365 return 0;
1366}
1367
1368int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
1369 if (m_debug.out_buffer_log && !m_debug.outfile) {
1370 sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
1371 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
1372 m_debug.outfile = fopen (m_debug.outfile_name, "ab");
1373 if (!m_debug.outfile) {
1374 DEBUG_PRINT_HIGH("Failed to open output file: %s for logging\n", m_debug.outfile);
1375 m_debug.outfile_name[0] = '\0';
1376 return -1;
1377 }
1378 }
1379 if (m_debug.outfile && buffer && buffer->nFilledLen) {
1380 int buf_index = buffer - m_out_mem_ptr;
1381 int stride = drv_ctx.video_resolution.stride;
1382 int scanlines = drv_ctx.video_resolution.scan_lines;
1383 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
1384 unsigned i;
1385 int bytes_written = 0;
1386 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
1387 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1388 temp += stride;
1389 }
1390 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
1391 int stride_c = stride;
1392 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
1393 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
1394 temp += stride_c;
1395 }
1396 }
1397 return 0;
1398}
1399
Shalaj Jain273b3e02012-06-22 19:08:03 -07001400/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001401 FUNCTION
1402 omx_vdec::ComponentInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07001403
Arun Menon906de572013-06-18 17:01:40 -07001404 DESCRIPTION
1405 Initialize the component.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001406
Arun Menon906de572013-06-18 17:01:40 -07001407 PARAMETERS
1408 ctxt -- Context information related to the self.
1409 id -- Event identifier. This could be any of the following:
1410 1. Command completion event
1411 2. Buffer done callback event
1412 3. Frame done callback event
Shalaj Jain273b3e02012-06-22 19:08:03 -07001413
Arun Menon906de572013-06-18 17:01:40 -07001414 RETURN VALUE
1415 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001416
Arun Menon906de572013-06-18 17:01:40 -07001417 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001418OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1419{
1420
Arun Menon906de572013-06-18 17:01:40 -07001421 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1422 struct v4l2_fmtdesc fdesc;
1423 struct v4l2_format fmt;
1424 struct v4l2_requestbuffers bufreq;
1425 struct v4l2_control control;
1426 struct v4l2_frmsizeenum frmsize;
1427 unsigned int alignment = 0,buffer_size = 0;
1428 int fds[2];
1429 int r,ret=0;
1430 bool codec_ambiguous = false;
1431 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
Sachin Shahc82a18f2013-03-29 14:45:38 -07001432
1433#ifdef _ANDROID_
Praveen Chavane9e56202013-09-19 03:48:16 -07001434 char platform_name[PROPERTY_VALUE_MAX];
Arun Menon906de572013-06-18 17:01:40 -07001435 property_get("ro.board.platform", platform_name, "0");
1436 if (!strncmp(platform_name, "msm8610", 7)) {
1437 device_name = (OMX_STRING)"/dev/video/q6_dec";
1438 }
Sachin Shahc82a18f2013-03-29 14:45:38 -07001439#endif
1440
Arun Menon906de572013-06-18 17:01:40 -07001441 if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1442 struct v4l2_control control;
1443 secure_mode = true;
1444 arbitrary_bytes = false;
1445 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
1446 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07001447
Arun Menon906de572013-06-18 17:01:40 -07001448 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001449
Jayasena Sangaraboinac453bd82013-08-01 14:02:52 -07001450 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d",
1451 drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001452
Arun Menon906de572013-06-18 17:01:40 -07001453 if (drv_ctx.video_driver_fd == 0) {
1454 DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again\n");
1455 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1456 close(0);
1457 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001458
Arun Menon906de572013-06-18 17:01:40 -07001459 if (drv_ctx.video_driver_fd < 0) {
1460 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1461 return OMX_ErrorInsufficientResources;
1462 }
1463 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1464 drv_ctx.frame_rate.fps_denominator = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001465
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001466 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Vinay Kalia184cd0f2013-04-29 18:26:42 -07001467 if (!ret) {
Arun Menon906de572013-06-18 17:01:40 -07001468 async_thread_created = true;
1469 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1470 }
1471 if (ret) {
1472 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1473 async_thread_created = false;
1474 return OMX_ErrorInsufficientResources;
Vinay Kaliadae8ad62013-04-26 20:42:10 -07001475 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001476
Shalaj Jain273b3e02012-06-22 19:08:03 -07001477#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07001478 outputExtradataFile = fopen (ouputextradatafilename, "ab");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001479#endif
1480
Arun Menon906de572013-06-18 17:01:40 -07001481 // Copy the role information which provides the decoder kind
1482 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001483
Arun Menon906de572013-06-18 17:01:40 -07001484 if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1485 OMX_MAX_STRINGNAME_SIZE)) {
1486 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1487 OMX_MAX_STRINGNAME_SIZE);
1488 drv_ctx.timestamp_adjust = true;
1489 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1490 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1491 output_capability=V4L2_PIX_FMT_MPEG4;
1492 /*Initialize Start Code for MPEG4*/
1493 codec_type_parse = CODEC_TYPE_MPEG4;
1494 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001495 } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1496 OMX_MAX_STRINGNAME_SIZE)) {
1497 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1498 OMX_MAX_STRINGNAME_SIZE);
1499 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1500 output_capability = V4L2_PIX_FMT_MPEG2;
1501 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1502 /*Initialize Start Code for MPEG2*/
1503 codec_type_parse = CODEC_TYPE_MPEG2;
1504 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001505 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1506 OMX_MAX_STRINGNAME_SIZE)) {
1507 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1508 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1509 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1510 eCompressionFormat = OMX_VIDEO_CodingH263;
1511 output_capability = V4L2_PIX_FMT_H263;
1512 codec_type_parse = CODEC_TYPE_H263;
1513 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001514 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1515 OMX_MAX_STRINGNAME_SIZE)) {
1516 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1517 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1518 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1519 output_capability = V4L2_PIX_FMT_DIVX_311;
1520 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1521 codec_type_parse = CODEC_TYPE_DIVX;
1522 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001523
Arun Menon906de572013-06-18 17:01:40 -07001524 eRet = createDivxDrmContext();
1525 if (eRet != OMX_ErrorNone) {
1526 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1527 return eRet;
1528 }
1529 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1530 OMX_MAX_STRINGNAME_SIZE)) {
1531 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1532 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1533 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1534 output_capability = V4L2_PIX_FMT_DIVX;
1535 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1536 codec_type_parse = CODEC_TYPE_DIVX;
1537 codec_ambiguous = true;
1538 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001539
Arun Menon906de572013-06-18 17:01:40 -07001540 eRet = createDivxDrmContext();
1541 if (eRet != OMX_ErrorNone) {
1542 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1543 return eRet;
1544 }
1545 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1546 OMX_MAX_STRINGNAME_SIZE)) {
1547 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1548 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1549 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1550 output_capability = V4L2_PIX_FMT_DIVX;
1551 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1552 codec_type_parse = CODEC_TYPE_DIVX;
1553 codec_ambiguous = true;
1554 m_frame_parser.init_start_codes (codec_type_parse);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001555
Arun Menon906de572013-06-18 17:01:40 -07001556 eRet = createDivxDrmContext();
1557 if (eRet != OMX_ErrorNone) {
1558 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1559 return eRet;
1560 }
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001561
Arun Menon906de572013-06-18 17:01:40 -07001562 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1563 OMX_MAX_STRINGNAME_SIZE)) {
1564 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1565 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1566 output_capability=V4L2_PIX_FMT_H264;
1567 eCompressionFormat = OMX_VIDEO_CodingAVC;
1568 codec_type_parse = CODEC_TYPE_H264;
1569 m_frame_parser.init_start_codes (codec_type_parse);
1570 m_frame_parser.init_nal_length(nal_length);
Arun Menon906de572013-06-18 17:01:40 -07001571 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1572 OMX_MAX_STRINGNAME_SIZE)) {
1573 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1574 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1575 eCompressionFormat = OMX_VIDEO_CodingWMV;
1576 codec_type_parse = CODEC_TYPE_VC1;
1577 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
1578 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001579 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1580 OMX_MAX_STRINGNAME_SIZE)) {
1581 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1582 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1583 eCompressionFormat = OMX_VIDEO_CodingWMV;
1584 codec_type_parse = CODEC_TYPE_VC1;
1585 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
1586 m_frame_parser.init_start_codes (codec_type_parse);
Arun Menon906de572013-06-18 17:01:40 -07001587 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1588 OMX_MAX_STRINGNAME_SIZE)) {
1589 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1590 output_capability=V4L2_PIX_FMT_VP8;
1591 eCompressionFormat = OMX_VIDEO_CodingVPX;
1592 codec_type_parse = CODEC_TYPE_VP8;
1593 arbitrary_bytes = false;
Praneeth Paladugu2b2ef2d2013-04-10 22:04:51 -07001594
Arun Menon906de572013-06-18 17:01:40 -07001595 } else {
1596 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1597 eRet = OMX_ErrorInvalidComponentName;
1598 }
Arun Menon906de572013-06-18 17:01:40 -07001599 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001600
Arun Menon906de572013-06-18 17:01:40 -07001601 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08001602 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1603 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1604 if (!client_buffers.set_color_format(dest_color_format)) {
1605 DEBUG_PRINT_ERROR("\n Setting color format failed");
1606 eRet = OMX_ErrorInsufficientResources;
1607 }
1608
Arun Menon906de572013-06-18 17:01:40 -07001609 capture_capability= V4L2_PIX_FMT_NV12;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001610
Arun Menon906de572013-06-18 17:01:40 -07001611 struct v4l2_capability cap;
1612 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1613 if (ret) {
1614 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
1615 /*TODO: How to handle this case */
1616 } else {
1617 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
1618 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1619 cap.bus_info, cap.version, cap.capabilities);
1620 }
1621 ret=0;
1622 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1623 fdesc.index=0;
1624 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1625 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
1626 fdesc.pixelformat, fdesc.flags);
1627 fdesc.index++;
1628 }
1629 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1630 fdesc.index=0;
1631 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001632
Arun Menon906de572013-06-18 17:01:40 -07001633 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
1634 fdesc.pixelformat, fdesc.flags);
1635 fdesc.index++;
1636 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001637 update_resolution(320, 240, 320, 240);
Arun Menon906de572013-06-18 17:01:40 -07001638 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1639 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1640 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1641 fmt.fmt.pix_mp.pixelformat = output_capability;
1642 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1643 if (ret) {
1644 /*TODO: How to handle this case */
1645 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
1646 return OMX_ErrorInsufficientResources;
1647 }
1648 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
1649 if (codec_ambiguous) {
1650 if (output_capability == V4L2_PIX_FMT_DIVX) {
1651 struct v4l2_control divx_ctrl;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001652
Arun Menon906de572013-06-18 17:01:40 -07001653 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
1654 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
1655 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
1656 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
1657 } else {
1658 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
1659 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001660
Arun Menon906de572013-06-18 17:01:40 -07001661 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
1662 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
1663 if (ret) {
1664 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1665 }
1666 } else {
1667 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1668 }
1669 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001670
Arun Menon906de572013-06-18 17:01:40 -07001671 //Get the hardware capabilities
1672 memset((void *)&frmsize,0,sizeof(frmsize));
1673 frmsize.index = 0;
1674 frmsize.pixel_format = output_capability;
1675 ret = ioctl(drv_ctx.video_driver_fd,
1676 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1677 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1678 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1679 return OMX_ErrorHardware;
1680 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001681
Arun Menon906de572013-06-18 17:01:40 -07001682 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1683 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1684 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1685 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1686 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1687 }
Deva Ramasubramanian3c55b212013-06-18 15:03:49 -07001688
Arun Menon906de572013-06-18 17:01:40 -07001689 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1690 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1691 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1692 fmt.fmt.pix_mp.pixelformat = capture_capability;
1693 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1694 if (ret) {
1695 /*TODO: How to handle this case */
1696 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
1697 }
1698 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
1699 if (secure_mode) {
1700 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1701 control.value = 1;
1702 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1703 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1704 if (ret) {
1705 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1706 return OMX_ErrorInsufficientResources;
1707 }
1708 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001709
Arun Menon906de572013-06-18 17:01:40 -07001710 /*Get the Buffer requirements for input and output ports*/
1711 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1712 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1713 if (secure_mode) {
1714 drv_ctx.op_buf.alignment=SZ_1M;
1715 drv_ctx.ip_buf.alignment=SZ_1M;
1716 } else {
1717 drv_ctx.op_buf.alignment=SZ_4K;
1718 drv_ctx.ip_buf.alignment=SZ_4K;
1719 }
1720 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1721 drv_ctx.extradata = 0;
1722 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1723 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1724 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1725 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
1726 drv_ctx.idr_only_decoding = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001727
Vinay Kalia5713bb32013-01-16 18:39:59 -08001728 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001729#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001730 if (eRet == OMX_ErrorNone && !secure_mode)
1731 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001732#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001733 eRet=get_buffer_req(&drv_ctx.ip_buf);
1734 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1735 get_buffer_req(&drv_ctx.op_buf);
Arun Menon906de572013-06-18 17:01:40 -07001736 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1737 if (m_frame_parser.mutils == NULL) {
1738 m_frame_parser.mutils = new H264_Utils();
Shalaj Jain273b3e02012-06-22 19:08:03 -07001739
Arun Menon906de572013-06-18 17:01:40 -07001740 if (m_frame_parser.mutils == NULL) {
1741 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1742 eRet = OMX_ErrorInsufficientResources;
1743 } else {
1744 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1745 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1746 h264_scratch.nFilledLen = 0;
1747 h264_scratch.nOffset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001748
Arun Menon906de572013-06-18 17:01:40 -07001749 if (h264_scratch.pBuffer == NULL) {
1750 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1751 return OMX_ErrorInsufficientResources;
1752 }
1753 m_frame_parser.mutils->initialize_frame_checking_environment();
1754 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1755 }
1756 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001757
Arun Menon906de572013-06-18 17:01:40 -07001758 h264_parser = new h264_stream_parser();
1759 if (!h264_parser) {
1760 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1761 eRet = OMX_ErrorInsufficientResources;
1762 }
1763 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001764
Arun Menon906de572013-06-18 17:01:40 -07001765 if (pipe(fds)) {
1766 DEBUG_PRINT_ERROR("pipe creation failed\n");
1767 eRet = OMX_ErrorInsufficientResources;
1768 } else {
1769 int temp1[2];
1770 if (fds[0] == 0 || fds[1] == 0) {
1771 if (pipe (temp1)) {
1772 DEBUG_PRINT_ERROR("pipe creation failed\n");
1773 return OMX_ErrorInsufficientResources;
1774 }
1775 //close (fds[0]);
1776 //close (fds[1]);
1777 fds[0] = temp1 [0];
1778 fds[1] = temp1 [1];
1779 }
1780 m_pipe_in = fds[0];
1781 m_pipe_out = fds[1];
1782 msg_thread_created = true;
1783 r = pthread_create(&msg_thread_id,0,message_thread,this);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001784
Arun Menon906de572013-06-18 17:01:40 -07001785 if (r < 0) {
1786 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1787 msg_thread_created = false;
1788 eRet = OMX_ErrorInsufficientResources;
1789 }
1790 }
1791 }
1792
1793 if (eRet != OMX_ErrorNone) {
1794 DEBUG_PRINT_ERROR("\n Component Init Failed");
1795 } else {
1796 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1797 }
1798 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1799 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001800}
1801
1802/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001803 FUNCTION
1804 omx_vdec::GetComponentVersion
Shalaj Jain273b3e02012-06-22 19:08:03 -07001805
Arun Menon906de572013-06-18 17:01:40 -07001806 DESCRIPTION
1807 Returns the component version.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001808
Arun Menon906de572013-06-18 17:01:40 -07001809 PARAMETERS
1810 TBD.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001811
Arun Menon906de572013-06-18 17:01:40 -07001812 RETURN VALUE
1813 OMX_ErrorNone.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001814
Arun Menon906de572013-06-18 17:01:40 -07001815 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001816OMX_ERRORTYPE omx_vdec::get_component_version
Arun Menon906de572013-06-18 17:01:40 -07001817(
1818 OMX_IN OMX_HANDLETYPE hComp,
1819 OMX_OUT OMX_STRING componentName,
1820 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1821 OMX_OUT OMX_VERSIONTYPE* specVersion,
1822 OMX_OUT OMX_UUIDTYPE* componentUUID
1823 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001824{
Arun Menon906de572013-06-18 17:01:40 -07001825 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001826 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1827 return OMX_ErrorInvalidState;
1828 }
Arun Menon906de572013-06-18 17:01:40 -07001829 /* TBD -- Return the proper version */
1830 if (specVersion) {
1831 specVersion->nVersion = OMX_SPEC_VERSION;
1832 }
1833 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001834}
1835/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001836 FUNCTION
1837 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001838
Arun Menon906de572013-06-18 17:01:40 -07001839 DESCRIPTION
1840 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001841
Arun Menon906de572013-06-18 17:01:40 -07001842 PARAMETERS
1843 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001844
Arun Menon906de572013-06-18 17:01:40 -07001845 RETURN VALUE
1846 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001847
Arun Menon906de572013-06-18 17:01:40 -07001848 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001849OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001850 OMX_IN OMX_COMMANDTYPE cmd,
1851 OMX_IN OMX_U32 param1,
1852 OMX_IN OMX_PTR cmdData
1853 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001854{
1855 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
Arun Menon906de572013-06-18 17:01:40 -07001856 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07001857 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1858 return OMX_ErrorInvalidState;
1859 }
1860 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
Arun Menon906de572013-06-18 17:01:40 -07001861 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
1862 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
1863 "to invalid port: %lu", param1);
1864 return OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001865 }
1866 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1867 sem_wait(&m_cmd_lock);
1868 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1869 return OMX_ErrorNone;
1870}
1871
1872/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07001873 FUNCTION
1874 omx_vdec::SendCommand
Shalaj Jain273b3e02012-06-22 19:08:03 -07001875
Arun Menon906de572013-06-18 17:01:40 -07001876 DESCRIPTION
1877 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07001878
Arun Menon906de572013-06-18 17:01:40 -07001879 PARAMETERS
1880 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07001881
Arun Menon906de572013-06-18 17:01:40 -07001882 RETURN VALUE
1883 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07001884
Arun Menon906de572013-06-18 17:01:40 -07001885 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07001886OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07001887 OMX_IN OMX_COMMANDTYPE cmd,
1888 OMX_IN OMX_U32 param1,
1889 OMX_IN OMX_PTR cmdData
1890 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07001891{
Arun Menon906de572013-06-18 17:01:40 -07001892 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1893 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1894 int bFlag = 1,sem_posted = 0,ret=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001895
Arun Menon906de572013-06-18 17:01:40 -07001896 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1897 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1898 m_state, eState);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001899
Arun Menon906de572013-06-18 17:01:40 -07001900 if (cmd == OMX_CommandStateSet) {
1901 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1902 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1903 /***************************/
1904 /* Current State is Loaded */
1905 /***************************/
1906 if (m_state == OMX_StateLoaded) {
1907 if (eState == OMX_StateIdle) {
1908 //if all buffers are allocated or all ports disabled
1909 if (allocate_done() ||
1910 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
1911 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1912 } else {
1913 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1914 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1915 // Skip the event notification
1916 bFlag = 0;
1917 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001918 }
Arun Menon906de572013-06-18 17:01:40 -07001919 /* Requesting transition from Loaded to Loaded */
1920 else if (eState == OMX_StateLoaded) {
1921 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1922 post_event(OMX_EventError,OMX_ErrorSameState,\
1923 OMX_COMPONENT_GENERATE_EVENT);
1924 eRet = OMX_ErrorSameState;
1925 }
1926 /* Requesting transition from Loaded to WaitForResources */
1927 else if (eState == OMX_StateWaitForResources) {
1928 /* Since error is None , we will post an event
1929 at the end of this function definition */
1930 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1931 }
1932 /* Requesting transition from Loaded to Executing */
1933 else if (eState == OMX_StateExecuting) {
1934 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1935 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1936 OMX_COMPONENT_GENERATE_EVENT);
1937 eRet = OMX_ErrorIncorrectStateTransition;
1938 }
1939 /* Requesting transition from Loaded to Pause */
1940 else if (eState == OMX_StatePause) {
1941 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1942 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1943 OMX_COMPONENT_GENERATE_EVENT);
1944 eRet = OMX_ErrorIncorrectStateTransition;
1945 }
1946 /* Requesting transition from Loaded to Invalid */
1947 else if (eState == OMX_StateInvalid) {
1948 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1949 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1950 eRet = OMX_ErrorInvalidState;
1951 } else {
1952 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1953 eState);
1954 eRet = OMX_ErrorBadParameter;
1955 }
1956 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001957
Arun Menon906de572013-06-18 17:01:40 -07001958 /***************************/
1959 /* Current State is IDLE */
1960 /***************************/
1961 else if (m_state == OMX_StateIdle) {
1962 if (eState == OMX_StateLoaded) {
1963 if (release_done()) {
1964 /*
1965 Since error is None , we will post an event at the end
1966 of this function definition
1967 */
1968 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
1969 } else {
1970 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
1971 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1972 // Skip the event notification
1973 bFlag = 0;
1974 }
1975 }
1976 /* Requesting transition from Idle to Executing */
1977 else if (eState == OMX_StateExecuting) {
1978 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1979 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1980 bFlag = 1;
1981 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1982 m_state=OMX_StateExecuting;
1983 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
1984 }
1985 /* Requesting transition from Idle to Idle */
1986 else if (eState == OMX_StateIdle) {
1987 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
1988 post_event(OMX_EventError,OMX_ErrorSameState,\
1989 OMX_COMPONENT_GENERATE_EVENT);
1990 eRet = OMX_ErrorSameState;
1991 }
1992 /* Requesting transition from Idle to WaitForResources */
1993 else if (eState == OMX_StateWaitForResources) {
1994 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
1995 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1996 OMX_COMPONENT_GENERATE_EVENT);
1997 eRet = OMX_ErrorIncorrectStateTransition;
1998 }
1999 /* Requesting transition from Idle to Pause */
2000 else if (eState == OMX_StatePause) {
2001 /*To pause the Video core we need to start the driver*/
2002 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2003 NULL) < */0) {
2004 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
2005 omx_report_error ();
2006 eRet = OMX_ErrorHardware;
2007 } else {
2008 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2009 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
2010 bFlag = 0;
2011 }
2012 }
2013 /* Requesting transition from Idle to Invalid */
2014 else if (eState == OMX_StateInvalid) {
2015 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->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(): Idle --> %d Not Handled\n",eState);
2020 eRet = OMX_ErrorBadParameter;
2021 }
2022 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002023
Arun Menon906de572013-06-18 17:01:40 -07002024 /******************************/
2025 /* Current State is Executing */
2026 /******************************/
2027 else if (m_state == OMX_StateExecuting) {
2028 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
2029 /* Requesting transition from Executing to Idle */
2030 if (eState == OMX_StateIdle) {
2031 /* Since error is None , we will post an event
2032 at the end of this function definition
2033 */
2034 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
2035 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2036 if (!sem_posted) {
2037 sem_posted = 1;
2038 sem_post (&m_cmd_lock);
2039 execute_omx_flush(OMX_ALL);
2040 }
2041 bFlag = 0;
2042 }
2043 /* Requesting transition from Executing to Paused */
2044 else if (eState == OMX_StatePause) {
2045 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
2046 m_state = OMX_StatePause;
2047 bFlag = 1;
2048 }
2049 /* Requesting transition from Executing to Loaded */
2050 else if (eState == OMX_StateLoaded) {
2051 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2052 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2053 OMX_COMPONENT_GENERATE_EVENT);
2054 eRet = OMX_ErrorIncorrectStateTransition;
2055 }
2056 /* Requesting transition from Executing to WaitForResources */
2057 else if (eState == OMX_StateWaitForResources) {
2058 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2059 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2060 OMX_COMPONENT_GENERATE_EVENT);
2061 eRet = OMX_ErrorIncorrectStateTransition;
2062 }
2063 /* Requesting transition from Executing to Executing */
2064 else if (eState == OMX_StateExecuting) {
2065 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2066 post_event(OMX_EventError,OMX_ErrorSameState,\
2067 OMX_COMPONENT_GENERATE_EVENT);
2068 eRet = OMX_ErrorSameState;
2069 }
2070 /* Requesting transition from Executing to Invalid */
2071 else if (eState == OMX_StateInvalid) {
2072 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2073 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2074 eRet = OMX_ErrorInvalidState;
2075 } else {
2076 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2077 eRet = OMX_ErrorBadParameter;
2078 }
2079 }
2080 /***************************/
2081 /* Current State is Pause */
2082 /***************************/
2083 else if (m_state == OMX_StatePause) {
2084 /* Requesting transition from Pause to Executing */
2085 if (eState == OMX_StateExecuting) {
2086 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
2087 m_state = OMX_StateExecuting;
2088 bFlag = 1;
2089 }
2090 /* Requesting transition from Pause to Idle */
2091 else if (eState == OMX_StateIdle) {
2092 /* Since error is None , we will post an event
2093 at the end of this function definition */
2094 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2095 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2096 if (!sem_posted) {
2097 sem_posted = 1;
2098 sem_post (&m_cmd_lock);
2099 execute_omx_flush(OMX_ALL);
2100 }
2101 bFlag = 0;
2102 }
2103 /* Requesting transition from Pause to loaded */
2104 else if (eState == OMX_StateLoaded) {
2105 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2106 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2107 OMX_COMPONENT_GENERATE_EVENT);
2108 eRet = OMX_ErrorIncorrectStateTransition;
2109 }
2110 /* Requesting transition from Pause to WaitForResources */
2111 else if (eState == OMX_StateWaitForResources) {
2112 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2113 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2114 OMX_COMPONENT_GENERATE_EVENT);
2115 eRet = OMX_ErrorIncorrectStateTransition;
2116 }
2117 /* Requesting transition from Pause to Pause */
2118 else if (eState == OMX_StatePause) {
2119 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2120 post_event(OMX_EventError,OMX_ErrorSameState,\
2121 OMX_COMPONENT_GENERATE_EVENT);
2122 eRet = OMX_ErrorSameState;
2123 }
2124 /* Requesting transition from Pause to Invalid */
2125 else if (eState == OMX_StateInvalid) {
2126 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2127 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2128 eRet = OMX_ErrorInvalidState;
2129 } else {
2130 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2131 eRet = OMX_ErrorBadParameter;
2132 }
2133 }
2134 /***************************/
2135 /* Current State is WaitForResources */
2136 /***************************/
2137 else if (m_state == OMX_StateWaitForResources) {
2138 /* Requesting transition from WaitForResources to Loaded */
2139 if (eState == OMX_StateLoaded) {
2140 /* Since error is None , we will post an event
2141 at the end of this function definition */
2142 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2143 }
2144 /* Requesting transition from WaitForResources to WaitForResources */
2145 else if (eState == OMX_StateWaitForResources) {
2146 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2147 post_event(OMX_EventError,OMX_ErrorSameState,
2148 OMX_COMPONENT_GENERATE_EVENT);
2149 eRet = OMX_ErrorSameState;
2150 }
2151 /* Requesting transition from WaitForResources to Executing */
2152 else if (eState == OMX_StateExecuting) {
2153 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2154 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2155 OMX_COMPONENT_GENERATE_EVENT);
2156 eRet = OMX_ErrorIncorrectStateTransition;
2157 }
2158 /* Requesting transition from WaitForResources to Pause */
2159 else if (eState == OMX_StatePause) {
2160 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2161 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2162 OMX_COMPONENT_GENERATE_EVENT);
2163 eRet = OMX_ErrorIncorrectStateTransition;
2164 }
2165 /* Requesting transition from WaitForResources to Invalid */
2166 else if (eState == OMX_StateInvalid) {
2167 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2168 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2169 eRet = OMX_ErrorInvalidState;
2170 }
2171 /* Requesting transition from WaitForResources to Loaded -
2172 is NOT tested by Khronos TS */
2173
2174 } else {
2175 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2176 eRet = OMX_ErrorBadParameter;
2177 }
2178 }
2179 /********************************/
2180 /* Current State is Invalid */
2181 /*******************************/
2182 else if (m_state == OMX_StateInvalid) {
2183 /* State Transition from Inavlid to any state */
2184 if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2185 || OMX_StateIdle || OMX_StateExecuting
2186 || OMX_StatePause || OMX_StateInvalid)) {
2187 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2188 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2189 OMX_COMPONENT_GENERATE_EVENT);
2190 eRet = OMX_ErrorInvalidState;
2191 }
2192 } else if (cmd == OMX_CommandFlush) {
2193 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
2194 "with param1: %lu", param1);
2195 if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2196 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2197 }
2198 if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2199 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2200 }
2201 if (!sem_posted) {
2202 sem_posted = 1;
2203 DEBUG_PRINT_LOW("\n Set the Semaphore");
2204 sem_post (&m_cmd_lock);
2205 execute_omx_flush(param1);
2206 }
2207 bFlag = 0;
2208 } else if ( cmd == OMX_CommandPortEnable) {
2209 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
2210 "with param1: %lu", param1);
2211 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2212 m_inp_bEnabled = OMX_TRUE;
2213
2214 if ( (m_state == OMX_StateLoaded &&
2215 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2216 || allocate_input_done()) {
2217 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2218 OMX_COMPONENT_GENERATE_EVENT);
2219 } else {
2220 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2221 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2222 // Skip the event notification
2223 bFlag = 0;
2224 }
2225 }
2226 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2227 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2228 m_out_bEnabled = OMX_TRUE;
2229
2230 if ( (m_state == OMX_StateLoaded &&
2231 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2232 || (allocate_output_done())) {
2233 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2234 OMX_COMPONENT_GENERATE_EVENT);
2235
2236 } else {
2237 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2238 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2239 // Skip the event notification
2240 bFlag = 0;
2241 }
2242 }
2243 } else if (cmd == OMX_CommandPortDisable) {
2244 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
2245 "with param1: %lu", param1);
2246 if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2247 m_inp_bEnabled = OMX_FALSE;
2248 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2249 && release_input_done()) {
2250 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2251 OMX_COMPONENT_GENERATE_EVENT);
2252 } else {
2253 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2254 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2255 if (!sem_posted) {
2256 sem_posted = 1;
2257 sem_post (&m_cmd_lock);
2258 }
2259 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2260 }
2261
2262 // Skip the event notification
2263 bFlag = 0;
2264 }
2265 }
2266 if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2267 m_out_bEnabled = OMX_FALSE;
2268 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2269 if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2270 && release_output_done()) {
2271 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2272 OMX_COMPONENT_GENERATE_EVENT);
2273 } else {
2274 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2275 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2276 if (!sem_posted) {
2277 sem_posted = 1;
2278 sem_post (&m_cmd_lock);
2279 }
2280 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2281 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2282 }
2283 // Skip the event notification
2284 bFlag = 0;
2285
2286 }
2287 }
2288 } else {
2289 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2290 eRet = OMX_ErrorNotImplemented;
2291 }
2292 if (eRet == OMX_ErrorNone && bFlag) {
2293 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2294 }
2295 if (!sem_posted) {
2296 sem_post(&m_cmd_lock);
2297 }
2298
2299 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002300}
2301
2302/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002303 FUNCTION
2304 omx_vdec::ExecuteOmxFlush
Shalaj Jain273b3e02012-06-22 19:08:03 -07002305
Arun Menon906de572013-06-18 17:01:40 -07002306 DESCRIPTION
2307 Executes the OMX flush.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002308
Arun Menon906de572013-06-18 17:01:40 -07002309 PARAMETERS
2310 flushtype - input flush(1)/output flush(0)/ both.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002311
Arun Menon906de572013-06-18 17:01:40 -07002312 RETURN VALUE
2313 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002314
Arun Menon906de572013-06-18 17:01:40 -07002315 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002316bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2317{
Arun Menon906de572013-06-18 17:01:40 -07002318 bool bRet = false;
2319 struct v4l2_plane plane;
2320 struct v4l2_buffer v4l2_buf;
2321 struct v4l2_decoder_cmd dec;
2322 DEBUG_PRINT_LOW("in %s, flushing %d", __func__, flushType);
2323 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
2324 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002325
Arun Menon906de572013-06-18 17:01:40 -07002326 DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
Deva Ramasubramaniancc8fb902013-05-07 18:19:14 -07002327
Arun Menon906de572013-06-18 17:01:40 -07002328 if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
2329 output_flush_progress = true;
2330 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2331 } else {
2332 /* XXX: The driver/hardware does not support flushing of individual ports
2333 * in all states. So we pretty much need to flush both ports internally,
2334 * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
2335 * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
2336 * we automatically omit sending the FLUSH done for the "opposite" port. */
2337 input_flush_progress = true;
2338 output_flush_progress = true;
2339 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
2340 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002341
Arun Menon906de572013-06-18 17:01:40 -07002342 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
2343 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
2344 bRet = false;
2345 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002346
Arun Menon906de572013-06-18 17:01:40 -07002347 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002348}
2349/*=========================================================================
2350FUNCTION : execute_output_flush
2351
2352DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002353Executes the OMX flush at OUTPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002354
2355PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002356None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002357
2358RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002359true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002360==========================================================================*/
2361bool omx_vdec::execute_output_flush()
2362{
Arun Menon906de572013-06-18 17:01:40 -07002363 unsigned p1 = 0; // Parameter - 1
2364 unsigned p2 = 0; // Parameter - 2
2365 unsigned ident = 0;
2366 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002367
Arun Menon906de572013-06-18 17:01:40 -07002368 /*Generate FBD for all Buffers in the FTBq*/
2369 pthread_mutex_lock(&m_lock);
2370 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2371 while (m_ftb_q.m_size) {
2372 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2373 m_ftb_q.m_size,pending_output_buffers);
2374 m_ftb_q.pop_entry(&p1,&p2,&ident);
2375 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
2376 if (ident == m_fill_output_msg ) {
2377 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2378 } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2379 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2380 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002381 }
Arun Menon906de572013-06-18 17:01:40 -07002382 pthread_mutex_unlock(&m_lock);
2383 output_flush_progress = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002384
Arun Menon906de572013-06-18 17:01:40 -07002385 if (arbitrary_bytes) {
2386 prev_ts = LLONG_MAX;
2387 rst_prev_ts = true;
2388 }
2389 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2390 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002391}
2392/*=========================================================================
2393FUNCTION : execute_input_flush
2394
2395DESCRIPTION
Arun Menon906de572013-06-18 17:01:40 -07002396Executes the OMX flush at INPUT PORT.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002397
2398PARAMETERS
Arun Menon906de572013-06-18 17:01:40 -07002399None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002400
2401RETURN VALUE
Arun Menon906de572013-06-18 17:01:40 -07002402true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002403==========================================================================*/
2404bool omx_vdec::execute_input_flush()
2405{
Arun Menon906de572013-06-18 17:01:40 -07002406 unsigned i =0;
2407 unsigned p1 = 0; // Parameter - 1
2408 unsigned p2 = 0; // Parameter - 2
2409 unsigned ident = 0;
2410 bool bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002411
Arun Menon906de572013-06-18 17:01:40 -07002412 /*Generate EBD for all Buffers in the ETBq*/
2413 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002414
Arun Menon906de572013-06-18 17:01:40 -07002415 pthread_mutex_lock(&m_lock);
2416 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2417 while (m_etb_q.m_size) {
2418 m_etb_q.pop_entry(&p1,&p2,&ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002419
Arun Menon906de572013-06-18 17:01:40 -07002420 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2421 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2422 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2423 } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2424 pending_input_buffers++;
2425 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2426 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2427 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2428 } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
2429 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2430 (OMX_BUFFERHEADERTYPE *)p1);
2431 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2432 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002433 }
Arun Menon906de572013-06-18 17:01:40 -07002434 time_stamp_dts.flush_timestamp();
2435 /*Check if Heap Buffers are to be flushed*/
2436 if (arbitrary_bytes && !(codec_config_flag)) {
2437 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2438 h264_scratch.nFilledLen = 0;
2439 nal_count = 0;
2440 look_ahead_nal = false;
2441 frame_count = 0;
2442 h264_last_au_ts = LLONG_MAX;
2443 h264_last_au_flags = 0;
2444 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2445 m_demux_entries = 0;
2446 DEBUG_PRINT_LOW("\n Initialize parser");
2447 if (m_frame_parser.mutils) {
2448 m_frame_parser.mutils->initialize_frame_checking_environment();
2449 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002450
Arun Menon906de572013-06-18 17:01:40 -07002451 while (m_input_pending_q.m_size) {
2452 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2453 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2454 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002455
Arun Menon906de572013-06-18 17:01:40 -07002456 if (psource_frame) {
2457 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2458 psource_frame = NULL;
2459 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002460
Arun Menon906de572013-06-18 17:01:40 -07002461 if (pdest_frame) {
2462 pdest_frame->nFilledLen = 0;
2463 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2464 (unsigned int)NULL);
2465 pdest_frame = NULL;
2466 }
2467 m_frame_parser.flush();
2468 } else if (codec_config_flag) {
2469 DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2470 "is not sent to the driver yet");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002471 }
Arun Menon906de572013-06-18 17:01:40 -07002472 pthread_mutex_unlock(&m_lock);
2473 input_flush_progress = false;
2474 if (!arbitrary_bytes) {
2475 prev_ts = LLONG_MAX;
2476 rst_prev_ts = true;
2477 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002478#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07002479 if (m_debug_timestamp) {
2480 m_timestamp_list.reset_ts_list();
2481 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002482#endif
Arun Menon906de572013-06-18 17:01:40 -07002483 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2484 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002485}
2486
2487
2488/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002489 FUNCTION
2490 omx_vdec::SendCommandEvent
Shalaj Jain273b3e02012-06-22 19:08:03 -07002491
Arun Menon906de572013-06-18 17:01:40 -07002492 DESCRIPTION
2493 Send the event to decoder pipe. This is needed to generate the callbacks
2494 in decoder thread context.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002495
Arun Menon906de572013-06-18 17:01:40 -07002496 PARAMETERS
2497 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002498
Arun Menon906de572013-06-18 17:01:40 -07002499 RETURN VALUE
2500 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07002501
Arun Menon906de572013-06-18 17:01:40 -07002502 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002503bool omx_vdec::post_event(unsigned int p1,
Arun Menon906de572013-06-18 17:01:40 -07002504 unsigned int p2,
2505 unsigned int id)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002506{
Arun Menon906de572013-06-18 17:01:40 -07002507 bool bRet = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002508
2509
Arun Menon906de572013-06-18 17:01:40 -07002510 pthread_mutex_lock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002511
Arun Menon906de572013-06-18 17:01:40 -07002512 if (id == m_fill_output_msg ||
2513 id == OMX_COMPONENT_GENERATE_FBD) {
2514 m_ftb_q.insert_entry(p1,p2,id);
2515 } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2516 id == OMX_COMPONENT_GENERATE_EBD ||
2517 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2518 m_etb_q.insert_entry(p1,p2,id);
2519 } else {
2520 m_cmd_q.insert_entry(p1,p2,id);
2521 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002522
Arun Menon906de572013-06-18 17:01:40 -07002523 bRet = true;
2524 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2525 post_message(this, id);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002526
Arun Menon906de572013-06-18 17:01:40 -07002527 pthread_mutex_unlock(&m_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002528
Arun Menon906de572013-06-18 17:01:40 -07002529 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002530}
2531
2532OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2533{
Arun Menon906de572013-06-18 17:01:40 -07002534 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2535 if (!profileLevelType)
2536 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002537
Arun Menon906de572013-06-18 17:01:40 -07002538 if (profileLevelType->nPortIndex == 0) {
2539 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2540 if (profileLevelType->nProfileIndex == 0) {
2541 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2542 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002543
Arun Menon906de572013-06-18 17:01:40 -07002544 } else if (profileLevelType->nProfileIndex == 1) {
2545 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2546 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2547 } else if (profileLevelType->nProfileIndex == 2) {
2548 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2549 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2550 } else {
2551 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
2552 profileLevelType->nProfileIndex);
2553 eRet = OMX_ErrorNoMore;
2554 }
2555 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2556 if (profileLevelType->nProfileIndex == 0) {
2557 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2558 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2559 } else {
2560 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2561 eRet = OMX_ErrorNoMore;
2562 }
2563 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2564 if (profileLevelType->nProfileIndex == 0) {
2565 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2566 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2567 } else if (profileLevelType->nProfileIndex == 1) {
2568 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2569 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2570 } else {
2571 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2572 eRet = OMX_ErrorNoMore;
2573 }
2574 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
2575 eRet = OMX_ErrorNoMore;
2576 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2577 if (profileLevelType->nProfileIndex == 0) {
2578 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2579 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2580 } else if (profileLevelType->nProfileIndex == 1) {
2581 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2582 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2583 } else {
2584 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
2585 eRet = OMX_ErrorNoMore;
2586 }
2587 } else {
2588 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s\n", drv_ctx.kind);
2589 eRet = OMX_ErrorNoMore;
2590 }
2591 } else {
2592 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex);
2593 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002594 }
Arun Menon906de572013-06-18 17:01:40 -07002595 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002596}
2597
2598/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002599 FUNCTION
2600 omx_vdec::GetParameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002601
Arun Menon906de572013-06-18 17:01:40 -07002602 DESCRIPTION
2603 OMX Get Parameter method implementation
Shalaj Jain273b3e02012-06-22 19:08:03 -07002604
Arun Menon906de572013-06-18 17:01:40 -07002605 PARAMETERS
2606 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002607
Arun Menon906de572013-06-18 17:01:40 -07002608 RETURN VALUE
2609 Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002610
Arun Menon906de572013-06-18 17:01:40 -07002611 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002612OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002613 OMX_IN OMX_INDEXTYPE paramIndex,
2614 OMX_INOUT OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002615{
2616 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2617
2618 DEBUG_PRINT_LOW("get_parameter: \n");
Arun Menon906de572013-06-18 17:01:40 -07002619 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002620 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2621 return OMX_ErrorInvalidState;
2622 }
Arun Menon906de572013-06-18 17:01:40 -07002623 if (paramData == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002624 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2625 return OMX_ErrorBadParameter;
2626 }
Arun Menon906de572013-06-18 17:01:40 -07002627 switch ((unsigned long)paramIndex) {
2628 case OMX_IndexParamPortDefinition: {
2629 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2630 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2631 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2632 eRet = update_portdef(portDefn);
2633 if (eRet == OMX_ErrorNone)
2634 m_port_def = *portDefn;
2635 break;
2636 }
2637 case OMX_IndexParamVideoInit: {
2638 OMX_PORT_PARAM_TYPE *portParamType =
2639 (OMX_PORT_PARAM_TYPE *) paramData;
2640 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002641
Arun Menon906de572013-06-18 17:01:40 -07002642 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2643 portParamType->nSize = sizeof(portParamType);
2644 portParamType->nPorts = 2;
2645 portParamType->nStartPortNumber = 0;
2646 break;
2647 }
2648 case OMX_IndexParamVideoPortFormat: {
2649 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2650 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2651 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002652
Arun Menon906de572013-06-18 17:01:40 -07002653 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2654 portFmt->nSize = sizeof(portFmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002655
Arun Menon906de572013-06-18 17:01:40 -07002656 if (0 == portFmt->nPortIndex) {
2657 if (0 == portFmt->nIndex) {
2658 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2659 portFmt->eCompressionFormat = eCompressionFormat;
2660 } else {
2661 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2662 " NoMore compression formats\n");
2663 eRet = OMX_ErrorNoMore;
2664 }
2665 } else if (1 == portFmt->nPortIndex) {
2666 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002667
Arun Menon906de572013-06-18 17:01:40 -07002668 if (0 == portFmt->nIndex)
2669 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2670 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2671 else if (1 == portFmt->nIndex)
2672 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2673 else {
2674 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2675 " NoMore Color formats\n");
2676 eRet = OMX_ErrorNoMore;
2677 }
2678 DEBUG_PRINT_LOW("returning %d\n", portFmt->eColorFormat);
2679 } else {
2680 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2681 (int)portFmt->nPortIndex);
2682 eRet = OMX_ErrorBadPortIndex;
2683 }
2684 break;
2685 }
2686 /*Component should support this port definition*/
2687 case OMX_IndexParamAudioInit: {
2688 OMX_PORT_PARAM_TYPE *audioPortParamType =
2689 (OMX_PORT_PARAM_TYPE *) paramData;
2690 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2691 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2692 audioPortParamType->nSize = sizeof(audioPortParamType);
2693 audioPortParamType->nPorts = 0;
2694 audioPortParamType->nStartPortNumber = 0;
2695 break;
2696 }
2697 /*Component should support this port definition*/
2698 case OMX_IndexParamImageInit: {
2699 OMX_PORT_PARAM_TYPE *imagePortParamType =
2700 (OMX_PORT_PARAM_TYPE *) paramData;
2701 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2702 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2703 imagePortParamType->nSize = sizeof(imagePortParamType);
2704 imagePortParamType->nPorts = 0;
2705 imagePortParamType->nStartPortNumber = 0;
2706 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002707
Arun Menon906de572013-06-18 17:01:40 -07002708 }
2709 /*Component should support this port definition*/
2710 case OMX_IndexParamOtherInit: {
2711 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2712 paramIndex);
2713 eRet =OMX_ErrorUnsupportedIndex;
2714 break;
2715 }
2716 case OMX_IndexParamStandardComponentRole: {
2717 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2718 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2719 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2720 comp_role->nSize = sizeof(*comp_role);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002721
Arun Menon906de572013-06-18 17:01:40 -07002722 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2723 paramIndex);
2724 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2725 OMX_MAX_STRINGNAME_SIZE);
2726 break;
2727 }
2728 /* Added for parameter test */
2729 case OMX_IndexParamPriorityMgmt: {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002730
Arun Menon906de572013-06-18 17:01:40 -07002731 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2732 (OMX_PRIORITYMGMTTYPE *) paramData;
2733 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2734 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2735 priorityMgmType->nSize = sizeof(priorityMgmType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002736
Arun Menon906de572013-06-18 17:01:40 -07002737 break;
2738 }
2739 /* Added for parameter test */
2740 case OMX_IndexParamCompBufferSupplier: {
2741 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2742 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2743 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002744
Arun Menon906de572013-06-18 17:01:40 -07002745 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2746 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2747 if (0 == bufferSupplierType->nPortIndex)
2748 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2749 else if (1 == bufferSupplierType->nPortIndex)
2750 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2751 else
2752 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002753
2754
Arun Menon906de572013-06-18 17:01:40 -07002755 break;
2756 }
2757 case OMX_IndexParamVideoAvc: {
2758 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2759 paramIndex);
2760 break;
2761 }
2762 case OMX_IndexParamVideoH263: {
2763 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2764 paramIndex);
2765 break;
2766 }
2767 case OMX_IndexParamVideoMpeg4: {
2768 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2769 paramIndex);
2770 break;
2771 }
2772 case OMX_IndexParamVideoMpeg2: {
2773 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2774 paramIndex);
2775 break;
2776 }
2777 case OMX_IndexParamVideoProfileLevelQuerySupported: {
2778 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2779 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2780 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2781 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2782 break;
2783 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002784#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07002785 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
2786 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2787 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2788 if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002789
Arun Menon906de572013-06-18 17:01:40 -07002790 if (secure_mode) {
2791 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2792 GRALLOC_USAGE_PRIVATE_UNCACHED);
2793 } else {
2794 nativeBuffersUsage->nUsage =
2795 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2796 GRALLOC_USAGE_PRIVATE_UNCACHED);
2797 }
2798 } else {
2799 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
2800 eRet = OMX_ErrorBadParameter;
2801 }
2802 }
2803 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002804#endif
2805
Arun Menon906de572013-06-18 17:01:40 -07002806 default: {
2807 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2808 eRet =OMX_ErrorUnsupportedIndex;
2809 }
2810
Shalaj Jain273b3e02012-06-22 19:08:03 -07002811 }
2812
Arun Menon906de572013-06-18 17:01:40 -07002813 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
2814 drv_ctx.video_resolution.frame_width,
2815 drv_ctx.video_resolution.frame_height,
2816 drv_ctx.video_resolution.stride,
2817 drv_ctx.video_resolution.scan_lines);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002818
Arun Menon906de572013-06-18 17:01:40 -07002819 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002820}
2821
2822#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2823OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2824{
2825 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2826 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2827 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2828
Arun Menon906de572013-06-18 17:01:40 -07002829 if ((params == NULL) ||
2830 (params->nativeBuffer == NULL) ||
2831 (params->nativeBuffer->handle == NULL) ||
2832 !m_enable_android_native_buffers)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002833 return OMX_ErrorBadParameter;
2834 m_use_android_native_buffers = OMX_TRUE;
2835 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2836 private_handle_t *handle = (private_handle_t *)nBuf->handle;
Arun Menon906de572013-06-18 17:01:40 -07002837 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 -07002838 OMX_U8 *buffer = NULL;
Arun Menon906de572013-06-18 17:01:40 -07002839 if (!secure_mode) {
2840 buffer = (OMX_U8*)mmap(0, handle->size,
Shalaj Jain273b3e02012-06-22 19:08:03 -07002841 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
Arun Menon906de572013-06-18 17:01:40 -07002842 if (buffer == MAP_FAILED) {
2843 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2844 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002845 }
2846 }
2847 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2848 } else {
2849 eRet = OMX_ErrorBadParameter;
2850 }
2851 return eRet;
2852}
2853#endif
2854/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07002855 FUNCTION
2856 omx_vdec::Setparameter
Shalaj Jain273b3e02012-06-22 19:08:03 -07002857
Arun Menon906de572013-06-18 17:01:40 -07002858 DESCRIPTION
2859 OMX Set Parameter method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002860
Arun Menon906de572013-06-18 17:01:40 -07002861 PARAMETERS
2862 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002863
Arun Menon906de572013-06-18 17:01:40 -07002864 RETURN VALUE
2865 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07002866
Arun Menon906de572013-06-18 17:01:40 -07002867 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07002868OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07002869 OMX_IN OMX_INDEXTYPE paramIndex,
2870 OMX_IN OMX_PTR paramData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002871{
2872 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07002873 int ret=0;
2874 struct v4l2_format fmt;
Arun Menon906de572013-06-18 17:01:40 -07002875 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002876 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
2877 return OMX_ErrorInvalidState;
2878 }
Arun Menon906de572013-06-18 17:01:40 -07002879 if (paramData == NULL) {
2880 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
2881 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002882 }
Arun Menon906de572013-06-18 17:01:40 -07002883 if ((m_state != OMX_StateLoaded) &&
2884 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2885 (m_out_bEnabled == OMX_TRUE) &&
2886 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2887 (m_inp_bEnabled == OMX_TRUE)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07002888 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
2889 return OMX_ErrorIncorrectStateOperation;
2890 }
Arun Menon906de572013-06-18 17:01:40 -07002891 switch ((unsigned long)paramIndex) {
2892 case OMX_IndexParamPortDefinition: {
2893 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2894 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2895 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2896 //been called.
2897 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
2898 (int)portDefn->format.video.nFrameHeight,
2899 (int)portDefn->format.video.nFrameWidth);
2900 if (OMX_DirOutput == portDefn->eDir) {
2901 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
2902 m_display_id = portDefn->format.video.pNativeWindow;
2903 unsigned int buffer_size;
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07002904 DEBUG_PRINT_LOW("\n SetParam OP: WxH(%lu x %lu)\n",
2905 portDefn->format.video.nFrameWidth,
2906 portDefn->format.video.nFrameHeight);
2907 if (portDefn->format.video.nFrameHeight != 0x0 &&
2908 portDefn->format.video.nFrameWidth != 0x0) {
2909 update_resolution(portDefn->format.video.nFrameWidth,
2910 portDefn->format.video.nFrameHeight,
2911 portDefn->format.video.nFrameWidth,
2912 portDefn->format.video.nFrameHeight);
2913 eRet = is_video_session_supported();
2914 if (eRet)
2915 break;
2916 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2917 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2918 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2919 fmt.fmt.pix_mp.pixelformat = capture_capability;
2920 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);
2921 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2922 if (ret) {
2923 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2924 eRet = OMX_ErrorUnsupportedSetting;
2925 } else
2926 eRet = get_buffer_req(&drv_ctx.op_buf);
2927 }
2928
Arun Menon906de572013-06-18 17:01:40 -07002929 if (!client_buffers.get_buffer_req(buffer_size)) {
2930 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
2931 eRet = OMX_ErrorBadParameter;
2932 } else {
2933 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
2934 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
2935 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
2936 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
2937 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
2938 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
2939 drv_ctx.extradata_info.buffer_size;
2940 eRet = set_buffer_req(&drv_ctx.op_buf);
2941 if (eRet == OMX_ErrorNone)
2942 m_port_def = *portDefn;
2943 } else {
2944 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
2945 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
2946 portDefn->nBufferCountActual, portDefn->nBufferSize);
2947 eRet = OMX_ErrorBadParameter;
2948 }
2949 }
2950 } else if (OMX_DirInput == portDefn->eDir) {
2951 bool port_format_changed = false;
2952 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
2953 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
2954 // Frame rate only should be set if this is a "known value" or to
2955 // activate ts prediction logic (arbitrary mode only) sending input
2956 // timestamps with max value (LLONG_MAX).
2957 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
2958 portDefn->format.video.xFramerate >> 16);
2959 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
2960 drv_ctx.frame_rate.fps_denominator);
2961 if (!drv_ctx.frame_rate.fps_numerator) {
2962 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
2963 drv_ctx.frame_rate.fps_numerator = 30;
2964 }
2965 if (drv_ctx.frame_rate.fps_denominator)
2966 drv_ctx.frame_rate.fps_numerator = (int)
2967 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
2968 drv_ctx.frame_rate.fps_denominator = 1;
2969 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
2970 drv_ctx.frame_rate.fps_numerator;
2971 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
2972 frm_int, drv_ctx.frame_rate.fps_numerator /
2973 (float)drv_ctx.frame_rate.fps_denominator);
2974 }
2975 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
2976 if (drv_ctx.video_resolution.frame_height !=
2977 portDefn->format.video.nFrameHeight ||
2978 drv_ctx.video_resolution.frame_width !=
2979 portDefn->format.video.nFrameWidth) {
2980 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
2981 portDefn->format.video.nFrameWidth,
2982 portDefn->format.video.nFrameHeight);
2983 port_format_changed = true;
2984 if (portDefn->format.video.nFrameHeight != 0x0 &&
2985 portDefn->format.video.nFrameWidth != 0x0) {
2986 update_resolution(portDefn->format.video.nFrameWidth,
2987 portDefn->format.video.nFrameHeight,
2988 portDefn->format.video.nFrameWidth,
2989 portDefn->format.video.nFrameHeight);
2990 eRet = is_video_session_supported();
2991 if (eRet)
2992 break;
2993 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2994 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2995 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2996 fmt.fmt.pix_mp.pixelformat = output_capability;
2997 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);
2998 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2999 if (ret) {
3000 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3001 eRet = OMX_ErrorUnsupportedSetting;
3002 } else
3003 eRet = get_buffer_req(&drv_ctx.op_buf);
3004 }
3005 }
3006 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3007 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
3008 port_format_changed = true;
3009 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
3010 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3011 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3012 (~(buffer_prop->alignment - 1));
3013 eRet = set_buffer_req(buffer_prop);
3014 }
3015 if (false == port_format_changed) {
3016 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
3017 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3018 portDefn->nBufferCountActual, portDefn->nBufferSize);
3019 eRet = OMX_ErrorBadParameter;
3020 }
3021 } else if (portDefn->eDir == OMX_DirMax) {
3022 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3023 (int)portDefn->nPortIndex);
3024 eRet = OMX_ErrorBadPortIndex;
3025 }
3026 }
3027 break;
3028 case OMX_IndexParamVideoPortFormat: {
3029 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3030 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3031 int ret=0;
3032 struct v4l2_format fmt;
3033 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3034 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003035
Arun Menon906de572013-06-18 17:01:40 -07003036 if (1 == portFmt->nPortIndex) {
3037 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3038 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3039 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3040 fmt.fmt.pix_mp.pixelformat = capture_capability;
3041 enum vdec_output_fromat op_format;
3042 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3043 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
3044 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
3045 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
3046 else if (portFmt->eColorFormat ==
3047 (OMX_COLOR_FORMATTYPE)
3048 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3049 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3050 else
3051 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003052
Arun Menon906de572013-06-18 17:01:40 -07003053 if (eRet == OMX_ErrorNone) {
3054 drv_ctx.output_format = op_format;
3055 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3056 if (ret) {
3057 DEBUG_PRINT_ERROR("\n Set output format failed");
3058 eRet = OMX_ErrorUnsupportedSetting;
3059 /*TODO: How to handle this case */
3060 } else {
3061 eRet = get_buffer_req(&drv_ctx.op_buf);
3062 }
3063 }
3064 if (eRet == OMX_ErrorNone) {
3065 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3066 DEBUG_PRINT_ERROR("\n Set color format failed");
3067 eRet = OMX_ErrorBadParameter;
3068 }
3069 }
3070 }
3071 }
3072 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003073
Arun Menon906de572013-06-18 17:01:40 -07003074 case OMX_QcomIndexPortDefn: {
3075 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3076 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
3077 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
3078 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003079
Arun Menon906de572013-06-18 17:01:40 -07003080 /* Input port */
3081 if (portFmt->nPortIndex == 0) {
3082 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3083 if (secure_mode) {
3084 arbitrary_bytes = false;
3085 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3086 eRet = OMX_ErrorUnsupportedSetting;
3087 } else {
3088 arbitrary_bytes = true;
3089 }
3090 } else if (portFmt->nFramePackingFormat ==
3091 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3092 arbitrary_bytes = false;
3093 } else {
3094 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
3095 portFmt->nFramePackingFormat);
3096 eRet = OMX_ErrorUnsupportedSetting;
3097 }
3098 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3099 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3100 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3101 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3102 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3103 m_out_mem_region_smi = OMX_TRUE;
3104 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3105 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3106 m_use_output_pmem = OMX_TRUE;
3107 }
3108 }
3109 }
3110 }
3111 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003112
Arun Menon906de572013-06-18 17:01:40 -07003113 case OMX_IndexParamStandardComponentRole: {
3114 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3115 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3116 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3117 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003118
Arun Menon906de572013-06-18 17:01:40 -07003119 if ((m_state == OMX_StateLoaded)&&
3120 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3121 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3122 } else {
3123 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3124 return OMX_ErrorIncorrectStateOperation;
3125 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003126
Arun Menon906de572013-06-18 17:01:40 -07003127 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3128 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3129 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3130 } else {
3131 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3132 eRet =OMX_ErrorUnsupportedSetting;
3133 }
3134 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3135 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3136 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3137 } else {
3138 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3139 eRet = OMX_ErrorUnsupportedSetting;
3140 }
3141 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3142 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3143 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3144 } else {
3145 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3146 eRet =OMX_ErrorUnsupportedSetting;
3147 }
3148 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3149 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3150 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3151 } else {
3152 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3153 eRet = OMX_ErrorUnsupportedSetting;
3154 }
3155 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3156 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3157 ) {
3158 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3159 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3160 } else {
3161 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3162 eRet =OMX_ErrorUnsupportedSetting;
3163 }
3164 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3165 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3166 ) {
3167 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3168 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3169 } else {
3170 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3171 eRet =OMX_ErrorUnsupportedSetting;
3172 }
3173 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3174 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3175 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3176 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3177 } else {
3178 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3179 eRet = OMX_ErrorUnsupportedSetting;
3180 }
3181 } else {
3182 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3183 eRet = OMX_ErrorInvalidComponentName;
3184 }
3185 break;
3186 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003187
Arun Menon906de572013-06-18 17:01:40 -07003188 case OMX_IndexParamPriorityMgmt: {
3189 if (m_state != OMX_StateLoaded) {
3190 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3191 return OMX_ErrorIncorrectStateOperation;
3192 }
3193 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
3194 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
3195 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003196
Arun Menon906de572013-06-18 17:01:40 -07003197 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
3198 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003199
Arun Menon906de572013-06-18 17:01:40 -07003200 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3201 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003202
Arun Menon906de572013-06-18 17:01:40 -07003203 break;
3204 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003205
Arun Menon906de572013-06-18 17:01:40 -07003206 case OMX_IndexParamCompBufferSupplier: {
3207 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3208 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3209 bufferSupplierType->eBufferSupplier);
3210 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3211 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003212
Arun Menon906de572013-06-18 17:01:40 -07003213 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003214
Arun Menon906de572013-06-18 17:01:40 -07003215 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003216
Arun Menon906de572013-06-18 17:01:40 -07003217 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003218
Arun Menon906de572013-06-18 17:01:40 -07003219 }
3220 case OMX_IndexParamVideoAvc: {
3221 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3222 paramIndex);
3223 break;
3224 }
3225 case OMX_IndexParamVideoH263: {
3226 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3227 paramIndex);
3228 break;
3229 }
3230 case OMX_IndexParamVideoMpeg4: {
3231 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3232 paramIndex);
3233 break;
3234 }
3235 case OMX_IndexParamVideoMpeg2: {
3236 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3237 paramIndex);
3238 break;
3239 }
3240 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3241 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3242 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3243 struct v4l2_control control;
3244 int pic_order,rc=0;
3245 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3246 pictureOrder->eOutputPictureOrder);
3247 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3248 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3249 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3250 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3251 time_stamp_dts.set_timestamp_reorder_mode(false);
3252 } else
3253 eRet = OMX_ErrorBadParameter;
3254 if (eRet == OMX_ErrorNone) {
3255 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3256 control.value = pic_order;
3257 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3258 if (rc) {
3259 DEBUG_PRINT_ERROR("\n Set picture order failed");
3260 eRet = OMX_ErrorUnsupportedSetting;
3261 }
3262 }
3263 break;
3264 }
3265 case OMX_QcomIndexParamConcealMBMapExtraData:
3266 if (!secure_mode)
3267 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3268 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3269 else {
3270 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3271 eRet = OMX_ErrorUnsupportedSetting;
3272 }
3273 break;
3274 case OMX_QcomIndexParamFrameInfoExtraData: {
3275 if (!secure_mode)
3276 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3277 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3278 else {
3279 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3280 eRet = OMX_ErrorUnsupportedSetting;
3281 }
3282 break;
3283 }
3284 case OMX_QcomIndexParamInterlaceExtraData:
3285 if (!secure_mode)
3286 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3287 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3288 else {
3289 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3290 eRet = OMX_ErrorUnsupportedSetting;
3291 }
3292 break;
3293 case OMX_QcomIndexParamH264TimeInfo:
3294 if (!secure_mode)
3295 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3296 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3297 else {
3298 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3299 eRet = OMX_ErrorUnsupportedSetting;
3300 }
3301 break;
3302 case OMX_QcomIndexParamVideoDivx: {
3303 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3304 }
3305 break;
3306 case OMX_QcomIndexPlatformPvt: {
3307 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3308 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3309 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3310 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3311 eRet = OMX_ErrorUnsupportedSetting;
3312 } else {
3313 m_out_pvt_entry_pmem = OMX_TRUE;
3314 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3315 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3316 m_use_output_pmem = OMX_TRUE;
3317 }
3318 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003319
Arun Menon906de572013-06-18 17:01:40 -07003320 }
3321 break;
3322 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3323 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3324 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3325 struct v4l2_control control;
3326 int rc;
3327 drv_ctx.idr_only_decoding = 1;
3328 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3329 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3330 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3331 if (rc) {
3332 DEBUG_PRINT_ERROR("\n Set picture order failed");
3333 eRet = OMX_ErrorUnsupportedSetting;
3334 } else {
3335 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3336 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3337 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3338 if (rc) {
3339 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3340 eRet = OMX_ErrorUnsupportedSetting;
3341 }
3342 /*Setting sync frame decoding on driver might change buffer
3343 * requirements so update them here*/
3344 if (get_buffer_req(&drv_ctx.ip_buf)) {
3345 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer i/p requirements");
3346 eRet = OMX_ErrorUnsupportedSetting;
3347 }
3348 if (get_buffer_req(&drv_ctx.op_buf)) {
3349 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer o/p requirements");
3350 eRet = OMX_ErrorUnsupportedSetting;
3351 }
3352 }
3353 }
3354 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003355
Arun Menon906de572013-06-18 17:01:40 -07003356 case OMX_QcomIndexParamIndexExtraDataType: {
3357 if (!secure_mode) {
3358 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3359 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3360 (extradataIndexType->bEnabled == OMX_TRUE) &&
3361 (extradataIndexType->nPortIndex == 1)) {
3362 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
3363 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003364
Arun Menon906de572013-06-18 17:01:40 -07003365 }
3366 }
3367 }
3368 break;
3369 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003370#ifndef SMOOTH_STREAMING_DISABLED
Arun Menon906de572013-06-18 17:01:40 -07003371 struct v4l2_control control;
3372 struct v4l2_format fmt;
3373 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3374 control.value = 1;
3375 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3376 if (rc < 0) {
3377 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3378 eRet = OMX_ErrorHardware;
3379 }
Arun Menonbc0922f2013-06-24 13:02:15 -07003380#else
Arun Menon906de572013-06-18 17:01:40 -07003381 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003382#endif
Arun Menon906de572013-06-18 17:01:40 -07003383 }
3384 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003385#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003386 /* Need to allow following two set_parameters even in Idle
3387 * state. This is ANDROID architecture which is not in sync
3388 * with openmax standard. */
3389 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3390 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3391 if (enableNativeBuffers) {
3392 m_enable_android_native_buffers = enableNativeBuffers->enable;
3393 }
3394 }
3395 break;
3396 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3397 eRet = use_android_native_buffer(hComp, paramData);
3398 }
3399 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003400#endif
Arun Menon906de572013-06-18 17:01:40 -07003401 case OMX_QcomIndexParamEnableTimeStampReorder: {
3402 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3403 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3404 if (reorder->bEnable == OMX_TRUE) {
3405 frm_int =0;
3406 time_stamp_dts.set_timestamp_reorder_mode(true);
3407 } else
3408 time_stamp_dts.set_timestamp_reorder_mode(false);
3409 } else {
3410 time_stamp_dts.set_timestamp_reorder_mode(false);
3411 if (reorder->bEnable == OMX_TRUE) {
3412 eRet = OMX_ErrorUnsupportedSetting;
3413 }
3414 }
3415 }
3416 break;
3417 case OMX_IndexParamVideoProfileLevelCurrent: {
3418 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3419 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3420 if (pParam) {
3421 m_profile_lvl.eProfile = pParam->eProfile;
3422 m_profile_lvl.eLevel = pParam->eLevel;
3423 }
3424 break;
Arun Menon888aa852013-05-30 11:24:42 -07003425
Arun Menon906de572013-06-18 17:01:40 -07003426 }
Arun Menonbdb80b02013-08-12 17:45:54 -07003427#ifdef META_DATA_MODE_SUPPORTED
Arun Menone5652482013-08-04 13:33:05 -07003428 case OMX_QcomIndexParamVideoMetaBufferMode:
3429 {
3430 StoreMetaDataInBuffersParams *metabuffer =
3431 (StoreMetaDataInBuffersParams *)paramData;
3432 if (!metabuffer) {
3433 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3434 eRet = OMX_ErrorBadParameter;
3435 break;
3436 }
3437 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3438 //set property dynamic buffer mode to driver.
3439 struct v4l2_control control;
3440 struct v4l2_format fmt;
3441 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3442 if (metabuffer->bStoreMetaData == true) {
3443 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3444 } else {
3445 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3446 }
3447 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3448 if (!rc) {
3449 DEBUG_PRINT_HIGH(" %s buffer mode\n",
3450 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003451 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003452 } else {
3453 DEBUG_PRINT_ERROR("Failed to %s buffer mode\n",
3454 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3455 eRet = OMX_ErrorUnsupportedSetting;
3456 }
3457 } else {
3458 DEBUG_PRINT_ERROR(
3459 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %d\n",
3460 metabuffer->nPortIndex);
3461 eRet = OMX_ErrorUnsupportedSetting;
3462 }
3463 break;
3464 }
Arun Menonbdb80b02013-08-12 17:45:54 -07003465#endif
Praneeth Paladugu42306bb2013-08-27 22:01:28 -07003466 case OMX_QcomIndexParamVideoDownScalar: {
3467 QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
3468 struct v4l2_control control;
3469 int rc;
3470 if (pParam) {
3471 is_down_scalar_enabled = pParam->bEnable;
3472 if (is_down_scalar_enabled) {
3473 control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
3474 control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
3475 DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d\n",
3476 pParam->bEnable);
3477 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3478 if (rc < 0) {
3479 DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
3480 eRet = OMX_ErrorUnsupportedSetting;
3481 }
3482 control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
3483 control.value = 1;
3484 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3485 if (rc < 0) {
3486 DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
3487 eRet = OMX_ErrorUnsupportedSetting;
3488 }
3489 }
3490 }
3491 break;
3492 }
Arun Menon906de572013-06-18 17:01:40 -07003493 default: {
3494 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3495 eRet = OMX_ErrorUnsupportedIndex;
3496 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003497 }
Arun Menon906de572013-06-18 17:01:40 -07003498 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003499}
3500
3501/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003502 FUNCTION
3503 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003504
Arun Menon906de572013-06-18 17:01:40 -07003505 DESCRIPTION
3506 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003507
Arun Menon906de572013-06-18 17:01:40 -07003508 PARAMETERS
3509 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003510
Arun Menon906de572013-06-18 17:01:40 -07003511 RETURN VALUE
3512 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003513
Arun Menon906de572013-06-18 17:01:40 -07003514 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003515OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003516 OMX_IN OMX_INDEXTYPE configIndex,
3517 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003518{
Arun Menon906de572013-06-18 17:01:40 -07003519 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003520
Arun Menon906de572013-06-18 17:01:40 -07003521 if (m_state == OMX_StateInvalid) {
3522 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003523 return OMX_ErrorInvalidState;
3524 }
Arun Menon906de572013-06-18 17:01:40 -07003525
3526 switch ((unsigned long)configIndex) {
3527 case OMX_QcomIndexConfigInterlaced: {
3528 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3529 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3530 if (configFmt->nPortIndex == 1) {
3531 if (configFmt->nIndex == 0) {
3532 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3533 } else if (configFmt->nIndex == 1) {
3534 configFmt->eInterlaceType =
3535 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3536 } else if (configFmt->nIndex == 2) {
3537 configFmt->eInterlaceType =
3538 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3539 } else {
3540 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3541 " NoMore Interlaced formats\n");
3542 eRet = OMX_ErrorNoMore;
3543 }
3544
3545 } else {
3546 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3547 (int)configFmt->nPortIndex);
3548 eRet = OMX_ErrorBadPortIndex;
3549 }
3550 break;
3551 }
3552 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3553 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3554 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3555 decoderinstances->nNumOfInstances = 16;
3556 /*TODO: How to handle this case */
3557 break;
3558 }
3559 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3560 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3561 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3562 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3563 h264_parser->get_frame_pack_data(configFmt);
3564 } else {
3565 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3566 }
3567 break;
3568 }
3569 case OMX_IndexConfigCommonOutputCrop: {
3570 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3571 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3572 break;
3573 }
3574 default: {
3575 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3576 eRet = OMX_ErrorBadParameter;
3577 }
3578
Shalaj Jain273b3e02012-06-22 19:08:03 -07003579 }
Arun Menon906de572013-06-18 17:01:40 -07003580
3581 return eRet;
3582}
3583
3584/* ======================================================================
3585 FUNCTION
3586 omx_vdec::SetConfig
3587
3588 DESCRIPTION
3589 OMX Set Config method implementation
3590
3591 PARAMETERS
3592 <TBD>.
3593
3594 RETURN VALUE
3595 OMX Error None if successful.
3596 ========================================================================== */
3597OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3598 OMX_IN OMX_INDEXTYPE configIndex,
3599 OMX_IN OMX_PTR configData)
3600{
3601 if (m_state == OMX_StateInvalid) {
3602 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3603 return OMX_ErrorInvalidState;
3604 }
3605
3606 OMX_ERRORTYPE ret = OMX_ErrorNone;
3607 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3608
3609 DEBUG_PRINT_LOW("\n Set Config Called");
3610
3611 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3612 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3613 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3614 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
3615 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3616 OMX_U32 extra_size;
3617 // Parsing done here for the AVC atom is definitely not generic
3618 // Currently this piece of code is working, but certainly
3619 // not tested with all .mp4 files.
3620 // Incase of failure, we might need to revisit this
3621 // for a generic piece of code.
3622
3623 // Retrieve size of NAL length field
3624 // byte #4 contains the size of NAL lenght field
3625 nal_length = (config->pData[4] & 0x03) + 1;
3626
3627 extra_size = 0;
3628 if (nal_length > 2) {
3629 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3630 extra_size = (nal_length - 2) * 2;
3631 }
3632
3633 // SPS starts from byte #6
3634 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3635 OMX_U8 *pDestBuf;
3636 m_vendor_config.nPortIndex = config->nPortIndex;
3637
3638 // minus 6 --> SPS starts from byte #6
3639 // minus 1 --> picture param set byte to be ignored from avcatom
3640 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3641 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3642 OMX_U32 len;
3643 OMX_U8 index = 0;
3644 // case where SPS+PPS is sent as part of set_config
3645 pDestBuf = m_vendor_config.pData;
3646
3647 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
3648 m_vendor_config.nPortIndex,
3649 m_vendor_config.nDataSize,
3650 m_vendor_config.pData);
3651 while (index < 2) {
3652 uint8 *psize;
3653 len = *pSrcBuf;
3654 len = len << 8;
3655 len |= *(pSrcBuf + 1);
3656 psize = (uint8 *) & len;
3657 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3658 for (unsigned int i = 0; i < nal_length; i++) {
3659 pDestBuf[i] = psize[nal_length - 1 - i];
3660 }
3661 //memcpy(pDestBuf,pSrcBuf,(len+2));
3662 pDestBuf += len + nal_length;
3663 pSrcBuf += len + 2;
3664 index++;
3665 pSrcBuf++; // skip picture param set
3666 len = 0;
3667 }
3668 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3669 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3670 m_vendor_config.nPortIndex = config->nPortIndex;
3671 m_vendor_config.nDataSize = config->nDataSize;
3672 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3673 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3674 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3675 if (m_vendor_config.pData) {
3676 free(m_vendor_config.pData);
3677 m_vendor_config.pData = NULL;
3678 m_vendor_config.nDataSize = 0;
3679 }
3680
3681 if (((*((OMX_U32 *) config->pData)) &
3682 VC1_SP_MP_START_CODE_MASK) ==
3683 VC1_SP_MP_START_CODE) {
3684 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3685 m_vendor_config.nPortIndex = config->nPortIndex;
3686 m_vendor_config.nDataSize = config->nDataSize;
3687 m_vendor_config.pData =
3688 (OMX_U8 *) malloc(config->nDataSize);
3689 memcpy(m_vendor_config.pData, config->pData,
3690 config->nDataSize);
3691 m_vc1_profile = VC1_SP_MP_RCV;
3692 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
3693 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3694 m_vendor_config.nPortIndex = config->nPortIndex;
3695 m_vendor_config.nDataSize = config->nDataSize;
3696 m_vendor_config.pData =
3697 (OMX_U8 *) malloc((config->nDataSize));
3698 memcpy(m_vendor_config.pData, config->pData,
3699 config->nDataSize);
3700 m_vc1_profile = VC1_AP;
3701 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
3702 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3703 m_vendor_config.nPortIndex = config->nPortIndex;
3704 m_vendor_config.nDataSize = config->nDataSize;
3705 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3706 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3707 m_vc1_profile = VC1_SP_MP_RCV;
3708 } else {
3709 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3710 }
3711 }
3712 return ret;
3713 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3714 struct v4l2_control temp;
3715 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3716
3717 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3718 switch (pNal->nNaluBytes) {
3719 case 0:
3720 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3721 break;
3722 case 2:
3723 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3724 break;
3725 case 4:
3726 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3727 break;
3728 default:
3729 return OMX_ErrorUnsupportedSetting;
3730 }
3731
3732 if (!arbitrary_bytes) {
3733 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3734 * with start code, so only need to notify driver in frame by frame mode */
3735 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3736 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3737 return OMX_ErrorHardware;
3738 }
3739 }
3740
3741 nal_length = pNal->nNaluBytes;
3742 m_frame_parser.init_nal_length(nal_length);
3743
3744 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
3745 return ret;
3746 } else if (configIndex == OMX_IndexVendorVideoFrameRate) {
3747 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
3748 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps);
3749
3750 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3751 if (config->bEnabled) {
3752 if ((config->nFps >> 16) > 0) {
3753 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d",
3754 config->nFps >> 16);
3755 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3756 drv_ctx.frame_rate.fps_denominator);
3757
3758 if (!drv_ctx.frame_rate.fps_numerator) {
3759 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3760 drv_ctx.frame_rate.fps_numerator = 30;
3761 }
3762
3763 if (drv_ctx.frame_rate.fps_denominator) {
3764 drv_ctx.frame_rate.fps_numerator = (int)
3765 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3766 }
3767
3768 drv_ctx.frame_rate.fps_denominator = 1;
3769 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3770 drv_ctx.frame_rate.fps_numerator;
3771
3772 struct v4l2_outputparm oparm;
3773 /*XXX: we're providing timing info as seconds per frame rather than frames
3774 * per second.*/
3775 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3776 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3777
3778 struct v4l2_streamparm sparm;
3779 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3780 sparm.parm.output = oparm;
3781 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3782 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3783 performance might be affected");
3784 ret = OMX_ErrorHardware;
3785 }
3786 client_set_fps = true;
3787 } else {
3788 DEBUG_PRINT_ERROR("Frame rate not supported.");
3789 ret = OMX_ErrorUnsupportedSetting;
3790 }
3791 } else {
3792 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3793 client_set_fps = false;
3794 }
3795 } else {
3796 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3797 (int)config->nPortIndex);
3798 ret = OMX_ErrorBadPortIndex;
3799 }
3800
3801 return ret;
3802 }
3803
3804 return OMX_ErrorNotImplemented;
3805}
3806
3807/* ======================================================================
3808 FUNCTION
3809 omx_vdec::GetExtensionIndex
3810
3811 DESCRIPTION
3812 OMX GetExtensionIndex method implementaion. <TBD>
3813
3814 PARAMETERS
3815 <TBD>.
3816
3817 RETURN VALUE
3818 OMX Error None if everything successful.
3819
3820 ========================================================================== */
3821OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3822 OMX_IN OMX_STRING paramName,
3823 OMX_OUT OMX_INDEXTYPE* indexType)
3824{
3825 if (m_state == OMX_StateInvalid) {
3826 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3827 return OMX_ErrorInvalidState;
3828 } else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3829 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3830 } else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003831 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3832 }
3833#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003834 else if (!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003835 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Arun Menon906de572013-06-18 17:01:40 -07003836 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003837 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Arun Menon906de572013-06-18 17:01:40 -07003838 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003839 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3840 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Arun Menon906de572013-06-18 17:01:40 -07003841 } else if (!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003842 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3843 }
3844#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07003845#ifdef META_DATA_MODE_SUPPORTED
Arun Menone5652482013-08-04 13:33:05 -07003846 else if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers", sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) {
3847 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
3848 }
Arun Menonbdb80b02013-08-12 17:45:54 -07003849#endif
Arun Menon906de572013-06-18 17:01:40 -07003850 else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003851 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3852 return OMX_ErrorNotImplemented;
3853 }
3854 return OMX_ErrorNone;
3855}
3856
3857/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003858 FUNCTION
3859 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07003860
Arun Menon906de572013-06-18 17:01:40 -07003861 DESCRIPTION
3862 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003863
Arun Menon906de572013-06-18 17:01:40 -07003864 PARAMETERS
3865 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003866
Arun Menon906de572013-06-18 17:01:40 -07003867 RETURN VALUE
3868 Error None if everything is successful.
3869 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003870OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003871 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003872{
Arun Menon906de572013-06-18 17:01:40 -07003873 *state = m_state;
3874 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
3875 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003876}
3877
3878/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003879 FUNCTION
3880 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07003881
Arun Menon906de572013-06-18 17:01:40 -07003882 DESCRIPTION
3883 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003884
Arun Menon906de572013-06-18 17:01:40 -07003885 PARAMETERS
3886 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003887
Arun Menon906de572013-06-18 17:01:40 -07003888 RETURN VALUE
3889 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003890
Arun Menon906de572013-06-18 17:01:40 -07003891 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003892OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003893 OMX_IN OMX_U32 port,
3894 OMX_IN OMX_HANDLETYPE peerComponent,
3895 OMX_IN OMX_U32 peerPort,
3896 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003897{
Arun Menon906de572013-06-18 17:01:40 -07003898 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3899 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003900}
3901
3902/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003903 FUNCTION
3904 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07003905
Arun Menon906de572013-06-18 17:01:40 -07003906 DESCRIPTION
3907 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07003908
Arun Menon906de572013-06-18 17:01:40 -07003909 PARAMETERS
3910 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003911
Arun Menon906de572013-06-18 17:01:40 -07003912 RETURN VALUE
3913 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07003914
Arun Menon906de572013-06-18 17:01:40 -07003915 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003916OMX_ERRORTYPE omx_vdec::allocate_extradata()
3917{
3918#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003919 if (drv_ctx.extradata_info.buffer_size) {
3920 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
3921 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3922 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3923 free_ion_memory(&drv_ctx.extradata_info.ion);
3924 }
3925 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
3926 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
3927 drv_ctx.extradata_info.size, 4096,
3928 &drv_ctx.extradata_info.ion.ion_alloc_data,
3929 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
3930 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
3931 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
3932 return OMX_ErrorInsufficientResources;
3933 }
3934 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
3935 drv_ctx.extradata_info.size,
3936 PROT_READ|PROT_WRITE, MAP_SHARED,
3937 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
3938 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
3939 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
3940 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3941 free_ion_memory(&drv_ctx.extradata_info.ion);
3942 return OMX_ErrorInsufficientResources;
3943 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003944 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003945#endif
Arun Menon906de572013-06-18 17:01:40 -07003946 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003947}
3948
Arun Menon906de572013-06-18 17:01:40 -07003949void omx_vdec::free_extradata()
3950{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003951#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003952 if (drv_ctx.extradata_info.uaddr) {
3953 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3954 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3955 free_ion_memory(&drv_ctx.extradata_info.ion);
3956 }
3957 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003958#endif
3959}
3960
Shalaj Jain273b3e02012-06-22 19:08:03 -07003961OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07003962 OMX_IN OMX_HANDLETYPE hComp,
3963 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3964 OMX_IN OMX_U32 port,
3965 OMX_IN OMX_PTR appData,
3966 OMX_IN OMX_U32 bytes,
3967 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003968{
Arun Menon906de572013-06-18 17:01:40 -07003969 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3970 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
3971 unsigned i= 0; // Temporary counter
3972 struct vdec_setbuffer_cmd setbuffers;
3973 OMX_PTR privateAppData = NULL;
3974 private_handle_t *handle = NULL;
3975 OMX_U8 *buff = buffer;
3976 struct v4l2_buffer buf;
3977 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3978 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003979
Arun Menon906de572013-06-18 17:01:40 -07003980 if (!m_out_mem_ptr) {
3981 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
3982 eRet = allocate_output_headers();
3983 if (eRet == OMX_ErrorNone)
3984 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07003985 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003986
Arun Menon906de572013-06-18 17:01:40 -07003987 if (eRet == OMX_ErrorNone) {
3988 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
3989 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
3990 break;
3991 }
3992 }
3993 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003994
Arun Menon906de572013-06-18 17:01:40 -07003995 if (i >= drv_ctx.op_buf.actualcount) {
3996 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
3997 eRet = OMX_ErrorInsufficientResources;
3998 }
3999
Arun Menonbdb80b02013-08-12 17:45:54 -07004000#ifdef META_DATA_MODE_SUPPORTED
4001 if (dynamic_buf_mode) {
4002 *bufferHdr = (m_out_mem_ptr + i );
4003 (*bufferHdr)->pBuffer = NULL;
4004 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4005 enum v4l2_buf_type buf_type;
4006 int rr = 0;
4007 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4008 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4009 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
4010 return OMX_ErrorInsufficientResources;
4011 } else {
4012 streaming[CAPTURE_PORT] = true;
4013 DEBUG_PRINT_LOW("STREAMON Successful");
4014 }
4015 }
4016 BITMASK_SET(&m_out_bm_count,i);
4017 (*bufferHdr)->pAppPrivate = appData;
4018 (*bufferHdr)->pBuffer = buffer;
4019 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
4020 return eRet;
4021 }
4022#endif
Arun Menon906de572013-06-18 17:01:40 -07004023 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004024#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004025 if (m_enable_android_native_buffers) {
4026 if (m_use_android_native_buffers) {
4027 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4028 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4029 handle = (private_handle_t *)nBuf->handle;
4030 privateAppData = params->pAppPrivate;
4031 } else {
4032 handle = (private_handle_t *)buff;
4033 privateAppData = appData;
4034 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004035
Arun Menon906de572013-06-18 17:01:40 -07004036 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4037 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4038 " expected %u, got %lu",
4039 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4040 return OMX_ErrorBadParameter;
4041 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004042
Arun Menon906de572013-06-18 17:01:40 -07004043 if (!m_use_android_native_buffers) {
4044 if (!secure_mode) {
4045 buff = (OMX_U8*)mmap(0, handle->size,
4046 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4047 if (buff == MAP_FAILED) {
4048 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4049 return OMX_ErrorInsufficientResources;
4050 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004051 }
4052 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004053#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004054 native_buffer[i].nativehandle = handle;
4055 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004056#endif
Arun Menon906de572013-06-18 17:01:40 -07004057 if (!handle) {
4058 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4059 return OMX_ErrorBadParameter;
4060 }
4061 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4062 drv_ctx.ptr_outputbuffer[i].offset = 0;
4063 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4064 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4065 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4066 } else
4067#endif
4068
4069 if (!ouput_egl_buffers && !m_use_output_pmem) {
4070#ifdef USE_ION
4071 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4072 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4073 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4074 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4075 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
4076 DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd);
4077 return OMX_ErrorInsufficientResources;
4078 }
4079 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4080 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4081#else
4082 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4083 open (MEM_DEVICE,O_RDWR);
4084
4085 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
4086 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
4087 return OMX_ErrorInsufficientResources;
4088 }
4089
4090 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4091 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4092 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4093 open (MEM_DEVICE,O_RDWR);
4094 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
4095 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
4096 return OMX_ErrorInsufficientResources;
4097 }
4098 }
4099
4100 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4101 drv_ctx.op_buf.buffer_size,
4102 drv_ctx.op_buf.alignment)) {
4103 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4104 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4105 return OMX_ErrorInsufficientResources;
4106 }
4107#endif
4108 if (!secure_mode) {
4109 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4110 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4111 PROT_READ|PROT_WRITE, MAP_SHARED,
4112 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4113 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4114 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4115#ifdef USE_ION
4116 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4117#endif
4118 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
4119 return OMX_ErrorInsufficientResources;
4120 }
4121 }
4122 drv_ctx.ptr_outputbuffer[i].offset = 0;
4123 privateAppData = appData;
4124 } else {
4125
4126 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4127 if (!appData || !bytes ) {
4128 if (!secure_mode && !buffer) {
4129 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4130 return OMX_ErrorBadParameter;
4131 }
4132 }
4133
4134 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4135 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4136 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4137 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4138 !pmem_list->nEntries ||
4139 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4140 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4141 return OMX_ErrorBadParameter;
4142 }
4143 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4144 pmem_list->entryList->entry;
4145 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4146 pmem_info->pmem_fd);
4147 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4148 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4149 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4150 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4151 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4152 privateAppData = appData;
4153 }
4154 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4155 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4156
4157 *bufferHdr = (m_out_mem_ptr + i );
4158 if (secure_mode)
4159 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4160 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4161 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4162 sizeof (vdec_bufferpayload));
4163
4164 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4165 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4166 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4167
4168 buf.index = i;
4169 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4170 buf.memory = V4L2_MEMORY_USERPTR;
4171 plane[0].length = drv_ctx.op_buf.buffer_size;
4172 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4173 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4174 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4175 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4176 plane[0].data_offset = 0;
4177 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4178 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4179 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4180 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4181#ifdef USE_ION
4182 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4183#endif
4184 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4185 plane[extra_idx].data_offset = 0;
4186 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4187 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004188 return OMX_ErrorBadParameter;
4189 }
Arun Menon906de572013-06-18 17:01:40 -07004190 buf.m.planes = plane;
4191 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004192
Arun Menon906de572013-06-18 17:01:40 -07004193 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4194 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4195 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004196 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004197 }
4198
Arun Menon906de572013-06-18 17:01:40 -07004199 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4200 enum v4l2_buf_type buf_type;
4201 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4202 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4203 return OMX_ErrorInsufficientResources;
4204 } else {
4205 streaming[CAPTURE_PORT] = true;
4206 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004207 }
4208 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004209
Arun Menon906de572013-06-18 17:01:40 -07004210 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4211 if (m_enable_android_native_buffers) {
4212 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4213 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4214 } else {
4215 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004216 }
Arun Menon906de572013-06-18 17:01:40 -07004217 (*bufferHdr)->pAppPrivate = privateAppData;
4218 BITMASK_SET(&m_out_bm_count,i);
4219 }
4220 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004221}
4222
4223/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004224 FUNCTION
4225 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004226
Arun Menon906de572013-06-18 17:01:40 -07004227 DESCRIPTION
4228 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004229
Arun Menon906de572013-06-18 17:01:40 -07004230 PARAMETERS
4231 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004232
Arun Menon906de572013-06-18 17:01:40 -07004233 RETURN VALUE
4234 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004235
Arun Menon906de572013-06-18 17:01:40 -07004236 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004237OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004238 OMX_IN OMX_HANDLETYPE hComp,
4239 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4240 OMX_IN OMX_U32 port,
4241 OMX_IN OMX_PTR appData,
4242 OMX_IN OMX_U32 bytes,
4243 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004244{
Arun Menon906de572013-06-18 17:01:40 -07004245 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4246 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4247 if (!m_inp_heap_ptr)
4248 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4249 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4250 drv_ctx.ip_buf.actualcount);
4251 if (!m_phdr_pmem_ptr)
4252 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4253 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4254 drv_ctx.ip_buf.actualcount);
4255 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4256 DEBUG_PRINT_ERROR("Insufficent memory");
4257 eRet = OMX_ErrorInsufficientResources;
4258 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4259 input_use_buffer = true;
4260 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4261 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4262 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4263 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4264 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4265 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4266 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4267 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4268 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
4269 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4270 (unsigned)NULL, (unsigned)NULL)) {
4271 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4272 return OMX_ErrorInsufficientResources;
4273 }
4274 m_in_alloc_cnt++;
4275 } else {
4276 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4277 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004278 }
Arun Menon906de572013-06-18 17:01:40 -07004279 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004280}
4281
4282/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004283 FUNCTION
4284 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004285
Arun Menon906de572013-06-18 17:01:40 -07004286 DESCRIPTION
4287 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004288
Arun Menon906de572013-06-18 17:01:40 -07004289 PARAMETERS
4290 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004291
Arun Menon906de572013-06-18 17:01:40 -07004292 RETURN VALUE
4293 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004294
Arun Menon906de572013-06-18 17:01:40 -07004295 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004296OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004297 OMX_IN OMX_HANDLETYPE hComp,
4298 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4299 OMX_IN OMX_U32 port,
4300 OMX_IN OMX_PTR appData,
4301 OMX_IN OMX_U32 bytes,
4302 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004303{
Arun Menon906de572013-06-18 17:01:40 -07004304 OMX_ERRORTYPE error = OMX_ErrorNone;
4305 struct vdec_setbuffer_cmd setbuffers;
4306
4307 if (bufferHdr == NULL || bytes == 0) {
4308 if (!secure_mode && buffer == NULL) {
4309 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4310 return OMX_ErrorBadParameter;
4311 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004312 }
Arun Menon906de572013-06-18 17:01:40 -07004313 if (m_state == OMX_StateInvalid) {
4314 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4315 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004316 }
Arun Menon906de572013-06-18 17:01:40 -07004317 if (port == OMX_CORE_INPUT_PORT_INDEX)
4318 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4319 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4320 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4321 else {
4322 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4323 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004324 }
Arun Menon906de572013-06-18 17:01:40 -07004325 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4326 if (error == OMX_ErrorNone) {
4327 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4328 // Send the callback now
4329 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4330 post_event(OMX_CommandStateSet,OMX_StateIdle,
4331 OMX_COMPONENT_GENERATE_EVENT);
4332 }
4333 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4334 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4335 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4336 post_event(OMX_CommandPortEnable,
4337 OMX_CORE_INPUT_PORT_INDEX,
4338 OMX_COMPONENT_GENERATE_EVENT);
4339 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4340 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4341 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4342 post_event(OMX_CommandPortEnable,
4343 OMX_CORE_OUTPUT_PORT_INDEX,
4344 OMX_COMPONENT_GENERATE_EVENT);
4345 }
4346 }
4347 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004348}
4349
4350OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004351 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004352{
Arun Menon906de572013-06-18 17:01:40 -07004353 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4354 if (m_inp_heap_ptr[bufferindex].pBuffer)
4355 free(m_inp_heap_ptr[bufferindex].pBuffer);
4356 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4357 }
4358 if (pmem_bufferHdr)
4359 free_input_buffer(pmem_bufferHdr);
4360 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004361}
4362
4363OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4364{
Arun Menon906de572013-06-18 17:01:40 -07004365 unsigned int index = 0;
4366 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4367 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004368 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004369
Arun Menon906de572013-06-18 17:01:40 -07004370 index = bufferHdr - m_inp_mem_ptr;
4371 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4372
4373 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
4374 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4375 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4376 struct vdec_setbuffer_cmd setbuffers;
4377 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4378 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4379 sizeof (vdec_bufferpayload));
4380 if (!secure_mode) {
4381 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4382 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4383 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4384 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4385 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4386 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4387 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4388 }
4389 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4390 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4391 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4392 free(m_desc_buffer_ptr[index].buf_addr);
4393 m_desc_buffer_ptr[index].buf_addr = NULL;
4394 m_desc_buffer_ptr[index].desc_data_size = 0;
4395 }
4396#ifdef USE_ION
4397 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4398#endif
4399 }
4400 }
4401
4402 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004403}
4404
4405OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4406{
Arun Menon906de572013-06-18 17:01:40 -07004407 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004408
Arun Menon906de572013-06-18 17:01:40 -07004409 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4410 return OMX_ErrorBadParameter;
4411 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004412
Arun Menon906de572013-06-18 17:01:40 -07004413 index = bufferHdr - m_out_mem_ptr;
4414 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004415
Arun Menon906de572013-06-18 17:01:40 -07004416 if (index < drv_ctx.op_buf.actualcount
4417 && drv_ctx.ptr_outputbuffer) {
4418 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
4419 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004420
Arun Menon906de572013-06-18 17:01:40 -07004421 struct vdec_setbuffer_cmd setbuffers;
4422 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4423 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4424 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004425#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004426 if (m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004427 if (!secure_mode) {
Arun Menon906de572013-06-18 17:01:40 -07004428 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4429 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4430 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4431 }
Praveen Chavan212671f2013-04-05 20:00:42 -07004432 }
Arun Menon906de572013-06-18 17:01:40 -07004433 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4434 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004435#endif
Arun Menon906de572013-06-18 17:01:40 -07004436 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4437 if (!secure_mode) {
4438 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4439 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4440 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4441 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4442 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4443 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4444 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4445 }
4446 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4447 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004448#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004449 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004450#endif
Arun Menon906de572013-06-18 17:01:40 -07004451 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004452#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004453 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004454#endif
Arun Menon906de572013-06-18 17:01:40 -07004455 if (release_output_done()) {
4456 free_extradata();
4457 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004458 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004459
Arun Menon906de572013-06-18 17:01:40 -07004460 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004461
4462}
4463
4464OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004465 OMX_BUFFERHEADERTYPE **bufferHdr,
4466 OMX_U32 port,
4467 OMX_PTR appData,
4468 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004469{
Arun Menon906de572013-06-18 17:01:40 -07004470 OMX_BUFFERHEADERTYPE *input = NULL;
4471 unsigned char *buf_addr = NULL;
4472 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4473 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004474
Arun Menon906de572013-06-18 17:01:40 -07004475 /* Sanity Check*/
4476 if (bufferHdr == NULL) {
4477 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004478 }
4479
Arun Menon906de572013-06-18 17:01:40 -07004480 if (m_inp_heap_ptr == NULL) {
4481 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4482 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4483 drv_ctx.ip_buf.actualcount);
4484 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4485 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4486 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004487
Arun Menon906de572013-06-18 17:01:40 -07004488 if (m_inp_heap_ptr == NULL) {
4489 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4490 return OMX_ErrorInsufficientResources;
4491 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004492 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004493
Arun Menon906de572013-06-18 17:01:40 -07004494 /*Find a Free index*/
4495 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4496 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
4497 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4498 break;
4499 }
4500 }
4501
4502 if (i < drv_ctx.ip_buf.actualcount) {
4503 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4504
4505 if (buf_addr == NULL) {
4506 return OMX_ErrorInsufficientResources;
4507 }
4508
4509 *bufferHdr = (m_inp_heap_ptr + i);
4510 input = *bufferHdr;
4511 BITMASK_SET(&m_heap_inp_bm_count,i);
4512
4513 input->pBuffer = (OMX_U8 *)buf_addr;
4514 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4515 input->nVersion.nVersion = OMX_SPEC_VERSION;
4516 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4517 input->pAppPrivate = appData;
4518 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4519 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4520 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4521 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
4522 /*Add the Buffers to freeq*/
4523 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4524 (unsigned)NULL, (unsigned)NULL)) {
4525 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4526 return OMX_ErrorInsufficientResources;
4527 }
4528 } else {
4529 return OMX_ErrorBadParameter;
4530 }
4531
4532 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004533
4534}
4535
4536
4537/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004538 FUNCTION
4539 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004540
Arun Menon906de572013-06-18 17:01:40 -07004541 DESCRIPTION
4542 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004543
Arun Menon906de572013-06-18 17:01:40 -07004544 PARAMETERS
4545 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004546
Arun Menon906de572013-06-18 17:01:40 -07004547 RETURN VALUE
4548 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004549
Arun Menon906de572013-06-18 17:01:40 -07004550 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004551OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004552 OMX_IN OMX_HANDLETYPE hComp,
4553 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4554 OMX_IN OMX_U32 port,
4555 OMX_IN OMX_PTR appData,
4556 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004557{
4558
Arun Menon906de572013-06-18 17:01:40 -07004559 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4560 struct vdec_setbuffer_cmd setbuffers;
4561 OMX_BUFFERHEADERTYPE *input = NULL;
4562 unsigned i = 0;
4563 unsigned char *buf_addr = NULL;
4564 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004565
Arun Menon906de572013-06-18 17:01:40 -07004566 if (bytes != drv_ctx.ip_buf.buffer_size) {
4567 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
4568 bytes, drv_ctx.ip_buf.buffer_size);
4569 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004570 }
4571
Arun Menon906de572013-06-18 17:01:40 -07004572 if (!m_inp_mem_ptr) {
4573 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4574 drv_ctx.ip_buf.actualcount,
4575 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004576
Arun Menon906de572013-06-18 17:01:40 -07004577 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4578 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4579
4580 if (m_inp_mem_ptr == NULL) {
4581 return OMX_ErrorInsufficientResources;
4582 }
4583
4584 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4585 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4586
4587 if (drv_ctx.ptr_inputbuffer == NULL) {
4588 return OMX_ErrorInsufficientResources;
4589 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004590#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004591 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4592 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004593
Arun Menon906de572013-06-18 17:01:40 -07004594 if (drv_ctx.ip_buf_ion_info == NULL) {
4595 return OMX_ErrorInsufficientResources;
4596 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004597#endif
4598
Arun Menon906de572013-06-18 17:01:40 -07004599 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4600 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004601#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004602 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004603#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004604 }
4605 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004606
Arun Menon906de572013-06-18 17:01:40 -07004607 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4608 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4609 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4610 break;
4611 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004612 }
Arun Menon906de572013-06-18 17:01:40 -07004613
4614 if (i < drv_ctx.ip_buf.actualcount) {
4615 struct v4l2_buffer buf;
4616 struct v4l2_plane plane;
4617 int rc;
4618 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4619#ifdef USE_ION
4620 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4621 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4622 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4623 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4624 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4625 return OMX_ErrorInsufficientResources;
4626 }
4627 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4628#else
4629 pmem_fd = open (MEM_DEVICE,O_RDWR);
4630
4631 if (pmem_fd < 0) {
4632 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4633 return OMX_ErrorInsufficientResources;
4634 }
4635
4636 if (pmem_fd == 0) {
4637 pmem_fd = open (MEM_DEVICE,O_RDWR);
4638
4639 if (pmem_fd < 0) {
4640 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4641 return OMX_ErrorInsufficientResources;
4642 }
4643 }
4644
4645 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4646 drv_ctx.ip_buf.alignment)) {
4647 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4648 close(pmem_fd);
4649 return OMX_ErrorInsufficientResources;
4650 }
4651#endif
4652 if (!secure_mode) {
4653 buf_addr = (unsigned char *)mmap(NULL,
4654 drv_ctx.ip_buf.buffer_size,
4655 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4656
4657 if (buf_addr == MAP_FAILED) {
4658 close(pmem_fd);
4659#ifdef USE_ION
4660 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4661#endif
4662 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4663 return OMX_ErrorInsufficientResources;
4664 }
4665 }
4666 *bufferHdr = (m_inp_mem_ptr + i);
4667 if (secure_mode)
4668 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4669 else
4670 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4671 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4672 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4673 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4674 drv_ctx.ptr_inputbuffer [i].offset = 0;
4675
4676
4677 buf.index = i;
4678 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4679 buf.memory = V4L2_MEMORY_USERPTR;
4680 plane.bytesused = 0;
4681 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4682 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4683 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4684 plane.reserved[1] = 0;
4685 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4686 buf.m.planes = &plane;
4687 buf.length = 1;
4688
4689 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4690 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4691
4692 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4693
4694 if (rc) {
4695 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4696 /*TODO: How to handle this case */
4697 return OMX_ErrorInsufficientResources;
4698 }
4699
4700 input = *bufferHdr;
4701 BITMASK_SET(&m_inp_bm_count,i);
4702 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4703 if (secure_mode)
4704 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4705 else
4706 input->pBuffer = (OMX_U8 *)buf_addr;
4707 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4708 input->nVersion.nVersion = OMX_SPEC_VERSION;
4709 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4710 input->pAppPrivate = appData;
4711 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4712 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4713
4714 if (drv_ctx.disable_dmx) {
4715 eRet = allocate_desc_buffer(i);
4716 }
4717 } else {
4718 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4719 eRet = OMX_ErrorInsufficientResources;
4720 }
4721 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004722}
4723
4724
4725/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004726 FUNCTION
4727 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004728
Arun Menon906de572013-06-18 17:01:40 -07004729 DESCRIPTION
4730 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004731
Arun Menon906de572013-06-18 17:01:40 -07004732 PARAMETERS
4733 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004734
Arun Menon906de572013-06-18 17:01:40 -07004735 RETURN VALUE
4736 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004737
Arun Menon906de572013-06-18 17:01:40 -07004738 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004739OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004740 OMX_IN OMX_HANDLETYPE hComp,
4741 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4742 OMX_IN OMX_U32 port,
4743 OMX_IN OMX_PTR appData,
4744 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004745{
Arun Menon906de572013-06-18 17:01:40 -07004746 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4747 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4748 unsigned i= 0; // Temporary counter
4749 struct vdec_setbuffer_cmd setbuffers;
4750 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004751#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004752 int ion_device_fd =-1;
4753 struct ion_allocation_data ion_alloc_data;
4754 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004755#endif
Arun Menon906de572013-06-18 17:01:40 -07004756 if (!m_out_mem_ptr) {
4757 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4758 drv_ctx.op_buf.actualcount,
4759 drv_ctx.op_buf.buffer_size);
4760 int nBufHdrSize = 0;
4761 int nPlatformEntrySize = 0;
4762 int nPlatformListSize = 0;
4763 int nPMEMInfoSize = 0;
4764 int pmem_fd = -1;
4765 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004766
Arun Menon906de572013-06-18 17:01:40 -07004767 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4768 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4769 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004770
Arun Menon906de572013-06-18 17:01:40 -07004771 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4772 drv_ctx.op_buf.actualcount);
4773 nBufHdrSize = drv_ctx.op_buf.actualcount *
4774 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004775
Arun Menon906de572013-06-18 17:01:40 -07004776 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4777 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4778 nPlatformListSize = drv_ctx.op_buf.actualcount *
4779 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4780 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4781 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004782
Arun Menon906de572013-06-18 17:01:40 -07004783 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4784 sizeof(OMX_BUFFERHEADERTYPE),
4785 nPMEMInfoSize,
4786 nPlatformListSize);
4787 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4788 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004789#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004790 ion_device_fd = alloc_map_ion_memory(
4791 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4792 drv_ctx.op_buf.alignment,
4793 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4794 if (ion_device_fd < 0) {
4795 return OMX_ErrorInsufficientResources;
4796 }
4797 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004798#else
Arun Menon906de572013-06-18 17:01:40 -07004799 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004800
Arun Menon906de572013-06-18 17:01:40 -07004801 if (pmem_fd < 0) {
4802 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4803 drv_ctx.op_buf.buffer_size);
4804 return OMX_ErrorInsufficientResources;
4805 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004806
Arun Menon906de572013-06-18 17:01:40 -07004807 if (pmem_fd == 0) {
4808 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004809
Arun Menon906de572013-06-18 17:01:40 -07004810 if (pmem_fd < 0) {
4811 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4812 drv_ctx.op_buf.buffer_size);
4813 return OMX_ErrorInsufficientResources;
4814 }
4815 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004816
Arun Menon906de572013-06-18 17:01:40 -07004817 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4818 drv_ctx.op_buf.actualcount,
4819 drv_ctx.op_buf.alignment)) {
4820 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4821 close(pmem_fd);
4822 return OMX_ErrorInsufficientResources;
4823 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004824#endif
Arun Menon906de572013-06-18 17:01:40 -07004825 if (!secure_mode) {
4826 pmem_baseaddress = (unsigned char *)mmap(NULL,
4827 (drv_ctx.op_buf.buffer_size *
4828 drv_ctx.op_buf.actualcount),
4829 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4830 if (pmem_baseaddress == MAP_FAILED) {
4831 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4832 drv_ctx.op_buf.buffer_size);
4833 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004834#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004835 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004836#endif
Arun Menon906de572013-06-18 17:01:40 -07004837 return OMX_ErrorInsufficientResources;
4838 }
4839 }
4840 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4841 // Alloc mem for platform specific info
4842 char *pPtr=NULL;
4843 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4844 nPMEMInfoSize,1);
4845 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4846 calloc (sizeof(struct vdec_bufferpayload),
4847 drv_ctx.op_buf.actualcount);
4848 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4849 calloc (sizeof (struct vdec_output_frameinfo),
4850 drv_ctx.op_buf.actualcount);
4851#ifdef USE_ION
4852 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4853 calloc (sizeof(struct vdec_ion),
4854 drv_ctx.op_buf.actualcount);
4855#endif
4856
4857 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4858 && drv_ctx.ptr_respbuffer) {
4859 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4860 (drv_ctx.op_buf.buffer_size *
4861 drv_ctx.op_buf.actualcount);
4862 bufHdr = m_out_mem_ptr;
4863 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4864 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4865 (((char *) m_platform_list) + nPlatformListSize);
4866 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4867 (((char *) m_platform_entry) + nPlatformEntrySize);
4868 pPlatformList = m_platform_list;
4869 pPlatformEntry = m_platform_entry;
4870 pPMEMInfo = m_pmem_info;
4871
4872 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
4873
4874 // Settting the entire storage nicely
4875 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
4876 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
4877 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4878 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4879 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4880 // Set the values when we determine the right HxW param
4881 bufHdr->nAllocLen = bytes;
4882 bufHdr->nFilledLen = 0;
4883 bufHdr->pAppPrivate = appData;
4884 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4885 // Platform specific PMEM Information
4886 // Initialize the Platform Entry
4887 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
4888 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4889 pPlatformEntry->entry = pPMEMInfo;
4890 // Initialize the Platform List
4891 pPlatformList->nEntries = 1;
4892 pPlatformList->entryList = pPlatformEntry;
4893 // Keep pBuffer NULL till vdec is opened
4894 bufHdr->pBuffer = NULL;
4895 bufHdr->nOffset = 0;
4896
4897 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4898 pPMEMInfo->pmem_fd = 0;
4899 bufHdr->pPlatformPrivate = pPlatformList;
4900
4901 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
4902 m_pmem_info[i].pmem_fd = pmem_fd;
4903#ifdef USE_ION
4904 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
4905 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
4906 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
4907#endif
4908
4909 /*Create a mapping between buffers*/
4910 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
4911 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
4912 &drv_ctx.ptr_outputbuffer[i];
4913 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
4914 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4915 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
4916
4917 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
4918 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
4919 drv_ctx.ptr_outputbuffer[i].bufferaddr);
4920 // Move the buffer and buffer header pointers
4921 bufHdr++;
4922 pPMEMInfo++;
4923 pPlatformEntry++;
4924 pPlatformList++;
4925 }
4926 } else {
4927 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
4928 m_out_mem_ptr, pPtr);
4929 if (m_out_mem_ptr) {
4930 free(m_out_mem_ptr);
4931 m_out_mem_ptr = NULL;
4932 }
4933 if (pPtr) {
4934 free(pPtr);
4935 pPtr = NULL;
4936 }
4937 if (drv_ctx.ptr_outputbuffer) {
4938 free(drv_ctx.ptr_outputbuffer);
4939 drv_ctx.ptr_outputbuffer = NULL;
4940 }
4941 if (drv_ctx.ptr_respbuffer) {
4942 free(drv_ctx.ptr_respbuffer);
4943 drv_ctx.ptr_respbuffer = NULL;
4944 }
4945#ifdef USE_ION
4946 if (drv_ctx.op_buf_ion_info) {
4947 DEBUG_PRINT_LOW("\n Free o/p ion context");
4948 free(drv_ctx.op_buf_ion_info);
4949 drv_ctx.op_buf_ion_info = NULL;
4950 }
4951#endif
4952 eRet = OMX_ErrorInsufficientResources;
4953 }
4954 if (eRet == OMX_ErrorNone)
4955 eRet = allocate_extradata();
4956 }
4957
4958 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4959 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4960 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
4961 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004962 }
4963 }
Arun Menon906de572013-06-18 17:01:40 -07004964
4965 if (eRet == OMX_ErrorNone) {
4966 if (i < drv_ctx.op_buf.actualcount) {
4967 struct v4l2_buffer buf;
4968 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4969 int rc;
4970 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4971
4972 drv_ctx.ptr_outputbuffer[i].buffer_len =
4973 drv_ctx.op_buf.buffer_size;
4974
4975 *bufferHdr = (m_out_mem_ptr + i );
4976 if (secure_mode) {
4977 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4978 }
4979 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
4980
4981 buf.index = i;
4982 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4983 buf.memory = V4L2_MEMORY_USERPTR;
4984 plane[0].length = drv_ctx.op_buf.buffer_size;
4985 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4986 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004987#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004988 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004989#endif
Arun Menon906de572013-06-18 17:01:40 -07004990 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4991 plane[0].data_offset = 0;
4992 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4993 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4994 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4995 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 -07004996#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004997 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004998#endif
Arun Menon906de572013-06-18 17:01:40 -07004999 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5000 plane[extra_idx].data_offset = 0;
5001 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5002 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5003 return OMX_ErrorBadParameter;
5004 }
5005 buf.m.planes = plane;
5006 buf.length = drv_ctx.num_planes;
5007 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
5008 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5009 if (rc) {
5010 /*TODO: How to handle this case */
5011 return OMX_ErrorInsufficientResources;
5012 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005013
Arun Menon906de572013-06-18 17:01:40 -07005014 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5015 enum v4l2_buf_type buf_type;
5016 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5017 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5018 if (rc) {
5019 return OMX_ErrorInsufficientResources;
5020 } else {
5021 streaming[CAPTURE_PORT] = true;
5022 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5023 }
5024 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005025
Arun Menon906de572013-06-18 17:01:40 -07005026 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5027 (*bufferHdr)->pAppPrivate = appData;
5028 BITMASK_SET(&m_out_bm_count,i);
5029 } else {
5030 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5031 eRet = OMX_ErrorInsufficientResources;
5032 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005033 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005034
Arun Menon906de572013-06-18 17:01:40 -07005035 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005036}
5037
5038
5039// AllocateBuffer -- API Call
5040/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005041 FUNCTION
5042 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005043
Arun Menon906de572013-06-18 17:01:40 -07005044 DESCRIPTION
5045 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07005046
Arun Menon906de572013-06-18 17:01:40 -07005047 PARAMETERS
5048 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005049
Arun Menon906de572013-06-18 17:01:40 -07005050 RETURN VALUE
5051 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005052
Arun Menon906de572013-06-18 17:01:40 -07005053 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005054OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005055 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5056 OMX_IN OMX_U32 port,
5057 OMX_IN OMX_PTR appData,
5058 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005059{
5060 unsigned i = 0;
5061 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5062
5063 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005064 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005065 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5066 return OMX_ErrorInvalidState;
5067 }
5068
Arun Menon906de572013-06-18 17:01:40 -07005069 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5070 if (arbitrary_bytes) {
5071 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5072 } else {
5073 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5074 }
5075 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005076 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5077 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005078 } else {
5079 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5080 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005081 }
5082 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005083 if (eRet == OMX_ErrorNone) {
5084 if (allocate_done()) {
5085 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005086 // Send the callback now
5087 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5088 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005089 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005090 }
5091 }
Arun Menon906de572013-06-18 17:01:40 -07005092 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5093 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5094 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5095 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005096 OMX_CORE_INPUT_PORT_INDEX,
5097 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005098 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005099 }
Arun Menon906de572013-06-18 17:01:40 -07005100 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5101 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5102 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005103 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005104 OMX_CORE_OUTPUT_PORT_INDEX,
5105 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005106 }
5107 }
5108 }
5109 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5110 return eRet;
5111}
5112
5113// Free Buffer - API call
5114/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005115 FUNCTION
5116 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005117
Arun Menon906de572013-06-18 17:01:40 -07005118 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005119
Arun Menon906de572013-06-18 17:01:40 -07005120 PARAMETERS
5121 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005122
Arun Menon906de572013-06-18 17:01:40 -07005123 RETURN VALUE
5124 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005125
Arun Menon906de572013-06-18 17:01:40 -07005126 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005127OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005128 OMX_IN OMX_U32 port,
5129 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005130{
5131 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5132 unsigned int nPortIndex;
5133 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5134
Arun Menon906de572013-06-18 17:01:40 -07005135 if (m_state == OMX_StateIdle &&
5136 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005137 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
Arun Menon906de572013-06-18 17:01:40 -07005138 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5139 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005140 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Arun Menon906de572013-06-18 17:01:40 -07005141 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5142 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5143 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5144 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Arun Menon9f098152013-05-08 13:53:54 -07005145 DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port);
Arun Menon906de572013-06-18 17:01:40 -07005146 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005147 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5148 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005149 OMX_ErrorPortUnpopulated,
5150 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005151
5152 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005153 } else if (m_state != OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005154 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5155 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005156 OMX_ErrorPortUnpopulated,
5157 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005158 }
5159
Arun Menon906de572013-06-18 17:01:40 -07005160 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5161 /*Check if arbitrary bytes*/
5162 if (!arbitrary_bytes && !input_use_buffer)
5163 nPortIndex = buffer - m_inp_mem_ptr;
5164 else
5165 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005166
5167 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005168 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5169 // Clear the bit associated with it.
5170 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5171 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5172 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005173
Arun Menon906de572013-06-18 17:01:40 -07005174 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5175 if (m_phdr_pmem_ptr)
5176 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5177 } else {
5178 if (arbitrary_bytes) {
5179 if (m_phdr_pmem_ptr)
5180 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5181 else
5182 free_input_buffer(nPortIndex,NULL);
5183 } else
5184 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005185 }
Arun Menon906de572013-06-18 17:01:40 -07005186 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305187 if(release_input_done())
5188 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005189 /*Free the Buffer Header*/
5190 if (release_input_done()) {
5191 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5192 free_input_buffer_header();
5193 }
5194 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005195 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5196 eRet = OMX_ErrorBadPortIndex;
5197 }
5198
Arun Menon906de572013-06-18 17:01:40 -07005199 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5200 && release_input_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005201 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5202 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5203 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005204 OMX_CORE_INPUT_PORT_INDEX,
5205 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005206 }
Arun Menon906de572013-06-18 17:01:40 -07005207 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005208 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005209 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005210 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005211 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5212 // Clear the bit associated with it.
5213 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5214 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005215 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005216
Surajit Podder12aefac2013-08-06 18:43:32 +05305217 if(release_output_done()) {
5218 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5219 }
Arun Menon906de572013-06-18 17:01:40 -07005220 if (release_output_done()) {
5221 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005222 }
Arun Menon906de572013-06-18 17:01:40 -07005223 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005224 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5225 eRet = OMX_ErrorBadPortIndex;
5226 }
Arun Menon906de572013-06-18 17:01:40 -07005227 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5228 && release_output_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005229 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5230
Arun Menon906de572013-06-18 17:01:40 -07005231 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5232 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005233#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005234 if (m_enable_android_native_buffers) {
5235 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5236 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5237 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005238#endif
5239
Arun Menon906de572013-06-18 17:01:40 -07005240 post_event(OMX_CommandPortDisable,
5241 OMX_CORE_OUTPUT_PORT_INDEX,
5242 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005243 }
Arun Menon906de572013-06-18 17:01:40 -07005244 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005245 eRet = OMX_ErrorBadPortIndex;
5246 }
Arun Menon906de572013-06-18 17:01:40 -07005247 if ((eRet == OMX_ErrorNone) &&
5248 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5249 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005250 // Send the callback now
5251 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5252 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005253 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005254 }
5255 }
5256 return eRet;
5257}
5258
5259
5260/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005261 FUNCTION
5262 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005263
Arun Menon906de572013-06-18 17:01:40 -07005264 DESCRIPTION
5265 This routine is used to push the encoded video frames to
5266 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005267
Arun Menon906de572013-06-18 17:01:40 -07005268 PARAMETERS
5269 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005270
Arun Menon906de572013-06-18 17:01:40 -07005271 RETURN VALUE
5272 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005273
Arun Menon906de572013-06-18 17:01:40 -07005274 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005275OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005276 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005277{
Arun Menon906de572013-06-18 17:01:40 -07005278 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5279 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005280
Arun Menon906de572013-06-18 17:01:40 -07005281 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5282 codec_config_flag = true;
5283 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5284 } else {
5285 codec_config_flag = false;
5286 }
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07005287
Arun Menon906de572013-06-18 17:01:40 -07005288 if (m_state == OMX_StateInvalid) {
5289 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5290 return OMX_ErrorInvalidState;
5291 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005292
Arun Menon906de572013-06-18 17:01:40 -07005293 if (buffer == NULL) {
5294 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5295 return OMX_ErrorBadParameter;
5296 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005297
Arun Menon906de572013-06-18 17:01:40 -07005298 if (!m_inp_bEnabled) {
5299 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5300 return OMX_ErrorIncorrectStateOperation;
5301 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005302
Arun Menon906de572013-06-18 17:01:40 -07005303 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
5304 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
5305 return OMX_ErrorBadPortIndex;
5306 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005307
5308#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005309 if (iDivXDrmDecrypt) {
5310 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5311 if (drmErr != OMX_ErrorNone) {
5312 // this error can be ignored
5313 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5314 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005315 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005316#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005317 if (perf_flag) {
5318 if (!latency) {
5319 dec_time.stop();
5320 latency = dec_time.processing_time_us();
5321 dec_time.start();
5322 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005323 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005324
Arun Menon906de572013-06-18 17:01:40 -07005325 if (arbitrary_bytes) {
5326 nBufferIndex = buffer - m_inp_heap_ptr;
5327 } else {
5328 if (input_use_buffer == true) {
5329 nBufferIndex = buffer - m_inp_heap_ptr;
5330 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5331 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5332 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5333 buffer = &m_inp_mem_ptr[nBufferIndex];
5334 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5335 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5336 } else {
5337 nBufferIndex = buffer - m_inp_mem_ptr;
5338 }
5339 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005340
Arun Menon906de572013-06-18 17:01:40 -07005341 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
5342 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5343 return OMX_ErrorBadParameter;
5344 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005345
Arun Menon906de572013-06-18 17:01:40 -07005346 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5347 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5348 if (arbitrary_bytes) {
5349 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005350 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005351 } else {
5352 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5353 set_frame_rate(buffer->nTimeStamp);
5354 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5355 }
5356 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005357}
5358
5359/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005360 FUNCTION
5361 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005362
Arun Menon906de572013-06-18 17:01:40 -07005363 DESCRIPTION
5364 This routine is used to push the encoded video frames to
5365 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005366
Arun Menon906de572013-06-18 17:01:40 -07005367 PARAMETERS
5368 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005369
Arun Menon906de572013-06-18 17:01:40 -07005370 RETURN VALUE
5371 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005372
Arun Menon906de572013-06-18 17:01:40 -07005373 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005374OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005375 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005376{
Arun Menon906de572013-06-18 17:01:40 -07005377 int push_cnt = 0,i=0;
5378 unsigned nPortIndex = 0;
5379 OMX_ERRORTYPE ret = OMX_ErrorNone;
5380 struct vdec_input_frameinfo frameinfo;
5381 struct vdec_bufferpayload *temp_buffer;
5382 struct vdec_seqheader seq_header;
5383 bool port_setting_changed = true;
5384 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005385
Arun Menon906de572013-06-18 17:01:40 -07005386 /*Should we generate a Aync error event*/
5387 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
5388 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5389 return OMX_ErrorBadParameter;
5390 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005391
Arun Menon906de572013-06-18 17:01:40 -07005392 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005393
Arun Menon906de572013-06-18 17:01:40 -07005394 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
5395 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5396 nPortIndex);
5397 return OMX_ErrorBadParameter;
5398 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005399
Arun Menon906de572013-06-18 17:01:40 -07005400 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005401
Arun Menon906de572013-06-18 17:01:40 -07005402 /* return zero length and not an EOS buffer */
5403 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5404 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
5405 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5406 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5407 OMX_COMPONENT_GENERATE_EBD);
5408 return OMX_ErrorNone;
5409 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005410
5411
Arun Menon906de572013-06-18 17:01:40 -07005412 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5413 mp4StreamType psBits;
5414 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5415 psBits.numBytes = buffer->nFilledLen;
5416 mp4_headerparser.parseHeader(&psBits);
5417 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5418 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5419 if (not_coded_vop) {
5420 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
5421 buffer->nFilledLen,frame_count);
5422 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
5423 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5424 not_coded_vop = false;
5425 buffer->nFilledLen = 0;
5426 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005427 }
5428 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005429
Arun Menon906de572013-06-18 17:01:40 -07005430 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005431
Arun Menon906de572013-06-18 17:01:40 -07005432 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005433
Arun Menon906de572013-06-18 17:01:40 -07005434 ) {
5435 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5436 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5437 OMX_COMPONENT_GENERATE_EBD);
5438 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005439 }
5440
Arun Menon906de572013-06-18 17:01:40 -07005441 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005442
Arun Menon906de572013-06-18 17:01:40 -07005443 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) {
5444 return OMX_ErrorBadParameter;
5445 }
5446 /* If its first frame, H264 codec and reject is true, then parse the nal
5447 and get the profile. Based on this, reject the clip playback */
5448 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5449 m_reject_avc_1080p_mp) {
5450 first_frame = 1;
5451 DEBUG_PRINT_ERROR("\nParse nal to get the profile");
5452 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5453 NALU_TYPE_SPS);
5454 m_profile = h264_parser->get_profile();
5455 ret = is_video_session_supported();
5456 if (ret) {
5457 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5458 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5459 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5460 m_state = OMX_StateInvalid;
5461 return OMX_ErrorNone;
5462 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005463 }
5464
Arun Menon906de572013-06-18 17:01:40 -07005465 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5466 /*for use buffer we need to memcpy the data*/
5467 temp_buffer->buffer_len = buffer->nFilledLen;
5468
5469 if (input_use_buffer) {
5470 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5471 if (arbitrary_bytes) {
5472 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5473 } else {
5474 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5475 buffer->nFilledLen);
5476 }
5477 } else {
5478 return OMX_ErrorBadParameter;
5479 }
5480
5481 }
5482
5483 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5484 frameinfo.client_data = (void *) buffer;
5485 frameinfo.datalen = temp_buffer->buffer_len;
5486 frameinfo.flags = 0;
5487 frameinfo.offset = buffer->nOffset;
5488 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5489 frameinfo.pmem_offset = temp_buffer->offset;
5490 frameinfo.timestamp = buffer->nTimeStamp;
5491 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5492 DEBUG_PRINT_LOW("ETB: dmx enabled");
5493 if (m_demux_entries == 0) {
5494 extract_demux_addr_offsets(buffer);
5495 }
5496
5497 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5498 handle_demux_data(buffer);
5499 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5500 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5501 } else {
5502 frameinfo.desc_addr = NULL;
5503 frameinfo.desc_size = 0;
5504 }
5505 if (!arbitrary_bytes) {
5506 frameinfo.flags |= buffer->nFlags;
5507 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005508
5509#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005510 if (m_debug_timestamp) {
5511 if (arbitrary_bytes) {
5512 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5513 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5514 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5515 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5516 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5517 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005518 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005519#endif
5520
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005521log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005522
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005523if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005524 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5525 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5526 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005527
Arun Menon906de572013-06-18 17:01:40 -07005528 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5529 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5530 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5531 h264_scratch.nFilledLen = 0;
5532 nal_count = 0;
5533 look_ahead_nal = false;
5534 frame_count = 0;
5535 if (m_frame_parser.mutils)
5536 m_frame_parser.mutils->initialize_frame_checking_environment();
5537 m_frame_parser.flush();
5538 h264_last_au_ts = LLONG_MAX;
5539 h264_last_au_flags = 0;
5540 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5541 m_demux_entries = 0;
5542 }
5543 struct v4l2_buffer buf;
5544 struct v4l2_plane plane;
5545 memset( (void *)&buf, 0, sizeof(buf));
5546 memset( (void *)&plane, 0, sizeof(plane));
5547 int rc;
5548 unsigned long print_count;
5549 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005550 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Arun Menon906de572013-06-18 17:01:40 -07005551 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
5552 }
5553 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5554 buf.index = nPortIndex;
5555 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5556 buf.memory = V4L2_MEMORY_USERPTR;
5557 plane.bytesused = temp_buffer->buffer_len;
5558 plane.length = drv_ctx.ip_buf.buffer_size;
5559 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5560 (unsigned long)temp_buffer->offset;
5561 plane.reserved[0] = temp_buffer->pmem_fd;
5562 plane.reserved[1] = temp_buffer->offset;
5563 plane.data_offset = 0;
5564 buf.m.planes = &plane;
5565 buf.length = 1;
5566 if (frameinfo.timestamp >= LLONG_MAX) {
5567 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5568 }
5569 //assumption is that timestamp is in milliseconds
5570 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5571 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5572 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5573 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005574
Arun Menon906de572013-06-18 17:01:40 -07005575 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5576 if (rc) {
5577 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5578 return OMX_ErrorHardware;
5579 }
5580 if (!streaming[OUTPUT_PORT]) {
5581 enum v4l2_buf_type buf_type;
5582 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005583
Arun Menon906de572013-06-18 17:01:40 -07005584 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005585 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
Arun Menon906de572013-06-18 17:01:40 -07005586 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5587 if (!ret) {
5588 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
5589 streaming[OUTPUT_PORT] = true;
5590 } else {
5591 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
5592 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5593 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5594 OMX_COMPONENT_GENERATE_EBD);
5595 return OMX_ErrorBadParameter;
5596 }
5597 }
5598 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5599 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5600 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005601
Arun Menon906de572013-06-18 17:01:40 -07005602 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005603}
5604
5605/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005606 FUNCTION
5607 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005608
Arun Menon906de572013-06-18 17:01:40 -07005609 DESCRIPTION
5610 IL client uses this method to release the frame buffer
5611 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005612
Arun Menon906de572013-06-18 17:01:40 -07005613 PARAMETERS
5614 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005615
Arun Menon906de572013-06-18 17:01:40 -07005616 RETURN VALUE
5617 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005618
Arun Menon906de572013-06-18 17:01:40 -07005619 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005620OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005621 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005622{
Arun Menonbdb80b02013-08-12 17:45:54 -07005623#ifdef META_DATA_MODE_SUPPORTED
5624 if (dynamic_buf_mode) {
5625 private_handle_t *handle = NULL;
5626 struct VideoDecoderOutputMetaData *meta;
5627 OMX_U8 *buff = NULL;
5628 unsigned int nPortIndex = 0;
5629
5630 if (!buffer || !buffer->pBuffer) {
5631 DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
5632 return OMX_ErrorBadParameter;
5633 }
5634
5635 //get the buffer type and fd info
5636 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5637 handle = (private_handle_t *)meta->pHandle;
5638 DEBUG_PRINT_LOW("FTB: buftype: %d bufhndl: %p", meta->eType, meta->pHandle);
5639
5640 //map the buffer handle based on the size set on output port definition.
5641 if (!secure_mode) {
5642 buff = (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5643 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
5644 } else {
5645 buff = (OMX_U8*) buffer;
5646 }
5647
5648 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5649 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5650 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
5651 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5652 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = buff;
5653 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5654 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5655 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5656 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5657 }
5658#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07005659
Arun Menon906de572013-06-18 17:01:40 -07005660 if (m_state == OMX_StateInvalid) {
5661 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5662 return OMX_ErrorInvalidState;
5663 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005664
Arun Menon906de572013-06-18 17:01:40 -07005665 if (!m_out_bEnabled) {
5666 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5667 return OMX_ErrorIncorrectStateOperation;
5668 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005669
Arun Menon906de572013-06-18 17:01:40 -07005670 if (buffer == NULL ||
5671 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) {
5672 return OMX_ErrorBadParameter;
5673 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005674
Arun Menon906de572013-06-18 17:01:40 -07005675 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
5676 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
5677 return OMX_ErrorBadPortIndex;
5678 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005679
Arun Menon906de572013-06-18 17:01:40 -07005680 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5681 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5682 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005683}
5684/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005685 FUNCTION
5686 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005687
Arun Menon906de572013-06-18 17:01:40 -07005688 DESCRIPTION
5689 IL client uses this method to release the frame buffer
5690 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005691
Arun Menon906de572013-06-18 17:01:40 -07005692 PARAMETERS
5693 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005694
Arun Menon906de572013-06-18 17:01:40 -07005695 RETURN VALUE
5696 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005697
Arun Menon906de572013-06-18 17:01:40 -07005698 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005699OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005700 OMX_IN OMX_HANDLETYPE hComp,
5701 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005702{
Arun Menon906de572013-06-18 17:01:40 -07005703 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5704 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5705 unsigned nPortIndex = 0;
5706 struct vdec_fillbuffer_cmd fillbuffer;
5707 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5708 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005709
Arun Menon906de572013-06-18 17:01:40 -07005710 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005711
Arun Menon906de572013-06-18 17:01:40 -07005712 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5713 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005714
Arun Menon906de572013-06-18 17:01:40 -07005715 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5716 bufferAdd, bufferAdd->pBuffer);
5717 /*Return back the output buffer to client*/
5718 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
5719 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5720 buffer->nFilledLen = 0;
5721 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5722 return OMX_ErrorNone;
5723 }
5724 pending_output_buffers++;
5725 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5726 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5727 if (ptr_respbuffer) {
5728 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5729 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005730
Arun Menon906de572013-06-18 17:01:40 -07005731 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5732 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5733 buffer->nFilledLen = 0;
5734 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5735 pending_output_buffers--;
5736 return OMX_ErrorBadParameter;
5737 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005738
Arun Menon906de572013-06-18 17:01:40 -07005739 int rc = 0;
5740 struct v4l2_buffer buf;
5741 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5742 memset( (void *)&buf, 0, sizeof(buf));
5743 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5744 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005745
Arun Menon906de572013-06-18 17:01:40 -07005746 buf.index = nPortIndex;
5747 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5748 buf.memory = V4L2_MEMORY_USERPTR;
5749 plane[0].bytesused = buffer->nFilledLen;
5750 plane[0].length = drv_ctx.op_buf.buffer_size;
5751 plane[0].m.userptr =
5752 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5753 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5754 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5755 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5756 plane[0].data_offset = 0;
5757 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5758 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5759 plane[extra_idx].bytesused = 0;
5760 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5761 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 -07005762#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005763 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005764#endif
Arun Menon906de572013-06-18 17:01:40 -07005765 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5766 plane[extra_idx].data_offset = 0;
5767 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5768 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5769 return OMX_ErrorBadParameter;
5770 }
5771 buf.m.planes = plane;
5772 buf.length = drv_ctx.num_planes;
Arun Menonbdb80b02013-08-12 17:45:54 -07005773 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d\n",
5774 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5775
Arun Menon906de572013-06-18 17:01:40 -07005776 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5777 if (rc) {
5778 /*TODO: How to handle this case */
5779 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5780 }
Arun Menon906de572013-06-18 17:01:40 -07005781return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005782}
5783
5784/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005785 FUNCTION
5786 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005787
Arun Menon906de572013-06-18 17:01:40 -07005788 DESCRIPTION
5789 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005790
Arun Menon906de572013-06-18 17:01:40 -07005791 PARAMETERS
5792 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005793
Arun Menon906de572013-06-18 17:01:40 -07005794 RETURN VALUE
5795 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005796
Arun Menon906de572013-06-18 17:01:40 -07005797 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005798OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005799 OMX_IN OMX_CALLBACKTYPE* callbacks,
5800 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005801{
5802
Arun Menon906de572013-06-18 17:01:40 -07005803 m_cb = *callbacks;
5804 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5805 m_cb.EventHandler,m_cb.FillBufferDone);
5806 m_app_data = appData;
5807 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005808}
5809
5810/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005811 FUNCTION
5812 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005813
Arun Menon906de572013-06-18 17:01:40 -07005814 DESCRIPTION
5815 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005816
Arun Menon906de572013-06-18 17:01:40 -07005817 PARAMETERS
5818 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005819
Arun Menon906de572013-06-18 17:01:40 -07005820 RETURN VALUE
5821 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005822
Arun Menon906de572013-06-18 17:01:40 -07005823 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005824OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5825{
5826#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005827 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005828 delete iDivXDrmDecrypt;
5829 iDivXDrmDecrypt=NULL;
5830 }
5831#endif //_ANDROID_
5832
Shalaj Jain286b0062013-02-21 20:35:48 -08005833 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005834 if (OMX_StateLoaded != m_state) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005835 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
Arun Menon906de572013-06-18 17:01:40 -07005836 m_state);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005837 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005838 } else {
5839 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005840 }
5841
5842 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005843 if (m_out_mem_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005844 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005845 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5846 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005847 }
5848#ifdef _ANDROID_ICS_
5849 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5850#endif
5851 }
5852
5853 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005854 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005855 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005856 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5857 if (m_inp_mem_ptr)
5858 free_input_buffer (i,&m_inp_mem_ptr[i]);
5859 else
5860 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005861 }
5862 }
5863 free_input_buffer_header();
5864 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005865 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005866 free(h264_scratch.pBuffer);
5867 h264_scratch.pBuffer = NULL;
5868 }
5869
Arun Menon906de572013-06-18 17:01:40 -07005870 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005871 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005872 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005873 }
5874
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07005875 if (m_frame_parser.mutils) {
5876 DEBUG_PRINT_LOW("\n Free utils parser");
5877 delete (m_frame_parser.mutils);
5878 m_frame_parser.mutils = NULL;
5879 }
5880
Arun Menon906de572013-06-18 17:01:40 -07005881 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005882 free(m_platform_list);
5883 m_platform_list = NULL;
5884 }
Arun Menon906de572013-06-18 17:01:40 -07005885 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005886 free(m_vendor_config.pData);
5887 m_vendor_config.pData = NULL;
5888 }
5889
5890 // Reset counters in mesg queues
5891 m_ftb_q.m_size=0;
5892 m_cmd_q.m_size=0;
5893 m_etb_q.m_size=0;
5894 m_ftb_q.m_read = m_ftb_q.m_write =0;
5895 m_cmd_q.m_read = m_cmd_q.m_write =0;
5896 m_etb_q.m_read = m_etb_q.m_write =0;
5897#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005898 if (m_debug_timestamp) {
5899 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005900 }
5901#endif
5902
5903 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
5904 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07005905 // NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005906 DEBUG_PRINT_HIGH("\n Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07005907
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005908 if (m_debug.infile) {
5909 fclose(m_debug.infile);
5910 m_debug.infile = NULL;
5911 }
5912 if (m_debug.outfile) {
5913 fclose(m_debug.outfile);
5914 m_debug.outfile = NULL;
5915 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005916#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07005917 if (outputExtradataFile)
5918 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005919#endif
Arun Menon906de572013-06-18 17:01:40 -07005920 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
5921 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005922}
5923
5924/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005925 FUNCTION
5926 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07005927
Arun Menon906de572013-06-18 17:01:40 -07005928 DESCRIPTION
5929 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005930
Arun Menon906de572013-06-18 17:01:40 -07005931 PARAMETERS
5932 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005933
Arun Menon906de572013-06-18 17:01:40 -07005934 RETURN VALUE
5935 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005936
Arun Menon906de572013-06-18 17:01:40 -07005937 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005938OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005939 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5940 OMX_IN OMX_U32 port,
5941 OMX_IN OMX_PTR appData,
5942 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005943{
Arun Menon906de572013-06-18 17:01:40 -07005944 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
5945 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
5946 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005947
5948#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005949 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
5950 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005951#else
Arun Menon906de572013-06-18 17:01:40 -07005952 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005953#endif
Arun Menon906de572013-06-18 17:01:40 -07005954 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
5955 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
5956 DEBUG_PRINT_ERROR("\n ");
5957 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005958#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005959 if (m_display_id == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005960 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
5961 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005962 }
5963 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
5964 eglGetProcAddress("eglQueryImageKHR");
5965 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
5966 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
5967 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005968#else //with OMX test app
5969 struct temp_egl {
5970 int pmem_fd;
5971 int offset;
5972 };
5973 struct temp_egl *temp_egl_id = NULL;
5974 void * pmemPtr = (void *) eglImage;
5975 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07005976 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005977 fd = temp_egl_id->pmem_fd;
5978 offset = temp_egl_id->offset;
5979 }
5980#endif
5981 if (fd < 0) {
5982 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
5983 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005984 }
5985 pmem_info.pmem_fd = (OMX_U32) fd;
5986 pmem_info.offset = (OMX_U32) offset;
5987 pmem_entry.entry = (void *) &pmem_info;
5988 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5989 pmem_list.entryList = &pmem_entry;
5990 pmem_list.nEntries = 1;
5991 ouput_egl_buffers = true;
5992 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
5993 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
5994 (OMX_U8 *)pmemPtr)) {
5995 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
5996 return OMX_ErrorInsufficientResources;
5997 }
5998 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005999}
6000
6001/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006002 FUNCTION
6003 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07006004
Arun Menon906de572013-06-18 17:01:40 -07006005 DESCRIPTION
6006 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006007
Arun Menon906de572013-06-18 17:01:40 -07006008 PARAMETERS
6009 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006010
Arun Menon906de572013-06-18 17:01:40 -07006011 RETURN VALUE
6012 OMX Error None if everything is successful.
6013 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006014OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006015 OMX_OUT OMX_U8* role,
6016 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006017{
Arun Menon906de572013-06-18 17:01:40 -07006018 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006019
Arun Menon906de572013-06-18 17:01:40 -07006020 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6021 if ((0 == index) && role) {
6022 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6023 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6024 } else {
6025 eRet = OMX_ErrorNoMore;
6026 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006027 }
Arun Menon906de572013-06-18 17:01:40 -07006028 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6029 if ((0 == index) && role) {
6030 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6031 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6032 } else {
6033 eRet = OMX_ErrorNoMore;
6034 }
6035 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6036 if ((0 == index) && role) {
6037 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6038 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6039 } else {
6040 DEBUG_PRINT_LOW("\n No more roles \n");
6041 eRet = OMX_ErrorNoMore;
6042 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006043 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006044
Arun Menon906de572013-06-18 17:01:40 -07006045 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6046 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6047 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006048
Shalaj Jain273b3e02012-06-22 19:08:03 -07006049 {
Arun Menon906de572013-06-18 17:01:40 -07006050 if ((0 == index) && role) {
6051 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6052 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6053 } else {
6054 DEBUG_PRINT_LOW("\n No more roles \n");
6055 eRet = OMX_ErrorNoMore;
6056 }
6057 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6058 if ((0 == index) && role) {
6059 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6060 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6061 } else {
6062 DEBUG_PRINT_LOW("\n No more roles \n");
6063 eRet = OMX_ErrorNoMore;
6064 }
6065 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6066 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6067 ) {
6068 if ((0 == index) && role) {
6069 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6070 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6071 } else {
6072 DEBUG_PRINT_LOW("\n No more roles \n");
6073 eRet = OMX_ErrorNoMore;
6074 }
6075 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6076 if ((0 == index) && role) {
6077 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6078 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6079 } else {
6080 DEBUG_PRINT_LOW("\n No more roles \n");
6081 eRet = OMX_ErrorNoMore;
6082 }
6083 } else {
6084 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6085 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006086 }
Arun Menon906de572013-06-18 17:01:40 -07006087 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006088}
6089
6090
6091
6092
6093/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006094 FUNCTION
6095 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006096
Arun Menon906de572013-06-18 17:01:40 -07006097 DESCRIPTION
6098 Checks if entire buffer pool is allocated by IL Client or not.
6099 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006100
Arun Menon906de572013-06-18 17:01:40 -07006101 PARAMETERS
6102 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006103
Arun Menon906de572013-06-18 17:01:40 -07006104 RETURN VALUE
6105 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006106
Arun Menon906de572013-06-18 17:01:40 -07006107 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006108bool omx_vdec::allocate_done(void)
6109{
Arun Menon906de572013-06-18 17:01:40 -07006110 bool bRet = false;
6111 bool bRet_In = false;
6112 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006113
Arun Menon906de572013-06-18 17:01:40 -07006114 bRet_In = allocate_input_done();
6115 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006116
Arun Menon906de572013-06-18 17:01:40 -07006117 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006118 bRet = true;
6119 }
Arun Menon906de572013-06-18 17:01:40 -07006120
6121 return bRet;
6122}
6123/* ======================================================================
6124 FUNCTION
6125 omx_vdec::AllocateInputDone
6126
6127 DESCRIPTION
6128 Checks if I/P buffer pool is allocated by IL Client or not.
6129
6130 PARAMETERS
6131 None.
6132
6133 RETURN VALUE
6134 true/false.
6135
6136 ========================================================================== */
6137bool omx_vdec::allocate_input_done(void)
6138{
6139 bool bRet = false;
6140 unsigned i=0;
6141
6142 if (m_inp_mem_ptr == NULL) {
6143 return bRet;
6144 }
6145 if (m_inp_mem_ptr ) {
6146 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6147 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6148 break;
6149 }
6150 }
6151 }
6152 if (i == drv_ctx.ip_buf.actualcount) {
6153 bRet = true;
6154 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6155 }
6156 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6157 m_inp_bPopulated = OMX_TRUE;
6158 }
6159 return bRet;
6160}
6161/* ======================================================================
6162 FUNCTION
6163 omx_vdec::AllocateOutputDone
6164
6165 DESCRIPTION
6166 Checks if entire O/P buffer pool is allocated by IL Client or not.
6167
6168 PARAMETERS
6169 None.
6170
6171 RETURN VALUE
6172 true/false.
6173
6174 ========================================================================== */
6175bool omx_vdec::allocate_output_done(void)
6176{
6177 bool bRet = false;
6178 unsigned j=0;
6179
6180 if (m_out_mem_ptr == NULL) {
6181 return bRet;
6182 }
6183
6184 if (m_out_mem_ptr) {
6185 for (; j < drv_ctx.op_buf.actualcount; j++) {
6186 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6187 break;
6188 }
6189 }
6190 }
6191
6192 if (j == drv_ctx.op_buf.actualcount) {
6193 bRet = true;
6194 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6195 if (m_out_bEnabled)
6196 m_out_bPopulated = OMX_TRUE;
6197 }
6198
6199 return bRet;
6200}
6201
6202/* ======================================================================
6203 FUNCTION
6204 omx_vdec::ReleaseDone
6205
6206 DESCRIPTION
6207 Checks if IL client has released all the buffers.
6208
6209 PARAMETERS
6210 None.
6211
6212 RETURN VALUE
6213 true/false
6214
6215 ========================================================================== */
6216bool omx_vdec::release_done(void)
6217{
6218 bool bRet = false;
6219
6220 if (release_input_done()) {
6221 if (release_output_done()) {
6222 bRet = true;
6223 }
6224 }
6225 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006226}
6227
6228
6229/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006230 FUNCTION
6231 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006232
Arun Menon906de572013-06-18 17:01:40 -07006233 DESCRIPTION
6234 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006235
Arun Menon906de572013-06-18 17:01:40 -07006236 PARAMETERS
6237 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006238
Arun Menon906de572013-06-18 17:01:40 -07006239 RETURN VALUE
6240 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006241
Arun Menon906de572013-06-18 17:01:40 -07006242 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006243bool omx_vdec::release_output_done(void)
6244{
Arun Menon906de572013-06-18 17:01:40 -07006245 bool bRet = false;
6246 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006247
Arun Menon906de572013-06-18 17:01:40 -07006248 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6249 if (m_out_mem_ptr) {
6250 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6251 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6252 break;
6253 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006254 }
Arun Menon906de572013-06-18 17:01:40 -07006255 if (j == drv_ctx.op_buf.actualcount) {
6256 m_out_bm_count = 0;
6257 bRet = true;
6258 }
6259 } else {
6260 m_out_bm_count = 0;
6261 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006262 }
Arun Menon906de572013-06-18 17:01:40 -07006263 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006264}
6265/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006266 FUNCTION
6267 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006268
Arun Menon906de572013-06-18 17:01:40 -07006269 DESCRIPTION
6270 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006271
Arun Menon906de572013-06-18 17:01:40 -07006272 PARAMETERS
6273 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006274
Arun Menon906de572013-06-18 17:01:40 -07006275 RETURN VALUE
6276 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006277
Arun Menon906de572013-06-18 17:01:40 -07006278 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006279bool omx_vdec::release_input_done(void)
6280{
Arun Menon906de572013-06-18 17:01:40 -07006281 bool bRet = false;
6282 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006283
Arun Menon906de572013-06-18 17:01:40 -07006284 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6285 if (m_inp_mem_ptr) {
6286 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6287 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6288 break;
6289 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006290 }
Arun Menon906de572013-06-18 17:01:40 -07006291 if (j==drv_ctx.ip_buf.actualcount) {
6292 bRet = true;
6293 }
6294 } else {
6295 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006296 }
Arun Menon906de572013-06-18 17:01:40 -07006297 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006298}
6299
6300OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006301 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006302{
Arun Menon906de572013-06-18 17:01:40 -07006303 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6304 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) {
6305 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6306 return OMX_ErrorBadParameter;
6307 } else if (output_flush_progress) {
6308 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6309 buffer->nFilledLen = 0;
6310 buffer->nTimeStamp = 0;
6311 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6312 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6313 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006314 }
6315
Arun Menon906de572013-06-18 17:01:40 -07006316 if (m_debug_extradata) {
6317 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
6318 DEBUG_PRINT_HIGH("\n");
6319 DEBUG_PRINT_HIGH("***************************************************\n");
6320 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
6321 DEBUG_PRINT_HIGH("***************************************************\n");
6322 }
6323
6324 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
6325 DEBUG_PRINT_HIGH("\n");
6326 DEBUG_PRINT_HIGH("***************************************************\n");
6327 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
6328 DEBUG_PRINT_HIGH("***************************************************\n");
6329 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006330 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006331
6332
Arun Menon906de572013-06-18 17:01:40 -07006333 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6334 buffer, buffer->pBuffer);
6335 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006336
Arun Menonbdb80b02013-08-12 17:45:54 -07006337#ifdef META_DATA_MODE_SUPPORTED
6338 if (dynamic_buf_mode && !secure_mode) {
6339 unsigned int nPortIndex = 0;
6340 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6341 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6342 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6343 }
6344#endif
6345
Arun Menon906de572013-06-18 17:01:40 -07006346 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6347 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6348 if (!output_flush_progress)
6349 post_event((unsigned)NULL, (unsigned)NULL,
6350 OMX_COMPONENT_GENERATE_EOS_DONE);
6351
6352 if (psource_frame) {
6353 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6354 psource_frame = NULL;
6355 }
6356 if (pdest_frame) {
6357 pdest_frame->nFilledLen = 0;
6358 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6359 (unsigned)NULL);
6360 pdest_frame = NULL;
6361 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006362 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006363
Arun Menon906de572013-06-18 17:01:40 -07006364 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006365 log_output_buffers(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006366
Arun Menon906de572013-06-18 17:01:40 -07006367 /* For use buffer we need to copy the data */
6368 if (!output_flush_progress) {
6369 /* This is the error check for non-recoverable errros */
6370 bool is_duplicate_ts_valid = true;
6371 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006372
Arun Menon906de572013-06-18 17:01:40 -07006373 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6374 output_capability == V4L2_PIX_FMT_MPEG2 ||
6375 output_capability == V4L2_PIX_FMT_DIVX ||
6376 output_capability == V4L2_PIX_FMT_DIVX_311)
6377 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006378
Arun Menon906de572013-06-18 17:01:40 -07006379 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6380 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6381 if (mbaff) {
6382 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306383 }
Arun Menon906de572013-06-18 17:01:40 -07006384 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306385
Arun Menon906de572013-06-18 17:01:40 -07006386 if (buffer->nFilledLen > 0) {
6387 time_stamp_dts.get_next_timestamp(buffer,
6388 is_interlaced && is_duplicate_ts_valid);
6389 if (m_debug_timestamp) {
6390 {
6391 OMX_TICKS expected_ts = 0;
6392 m_timestamp_list.pop_min_ts(expected_ts);
6393 if (is_interlaced && is_duplicate_ts_valid) {
6394 m_timestamp_list.pop_min_ts(expected_ts);
6395 }
6396 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6397 buffer->nTimeStamp, expected_ts);
6398
6399 if (buffer->nTimeStamp != expected_ts) {
6400 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6401 }
6402 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306403 }
Arun Menon906de572013-06-18 17:01:40 -07006404 } else {
6405 m_inp_err_count++;
6406 time_stamp_dts.remove_time_stamp(
6407 buffer->nTimeStamp,
6408 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306409 }
Arun Menon906de572013-06-18 17:01:40 -07006410
6411
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006412 }
Arun Menon906de572013-06-18 17:01:40 -07006413 if (m_cb.FillBufferDone) {
6414 if (buffer->nFilledLen > 0) {
6415 handle_extradata(buffer);
6416 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6417 set_frame_rate(buffer->nTimeStamp);
6418 else if (arbitrary_bytes)
6419 adjust_timestamp(buffer->nTimeStamp);
6420 if (perf_flag) {
6421 if (!proc_frms) {
6422 dec_time.stop();
6423 latency = dec_time.processing_time_us() - latency;
6424 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6425 dec_time.start();
6426 fps_metrics.start();
6427 }
6428 proc_frms++;
6429 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6430 OMX_U64 proc_time = 0;
6431 fps_metrics.stop();
6432 proc_time = fps_metrics.processing_time_us();
6433 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006434 proc_frms, (float)proc_time / 1e6,
6435 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006436 proc_frms = 0;
6437 }
6438 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006439
6440#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006441 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006442
Arun Menon906de572013-06-18 17:01:40 -07006443 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6444 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6445 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6446 buffer->nFilledLen + 3)&(~3));
6447 while (p_extra &&
6448 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
6449 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6450 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6451 if (p_extra->eType == OMX_ExtraDataNone) {
6452 break;
6453 }
6454 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6455 }
6456 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006457#endif
Arun Menon906de572013-06-18 17:01:40 -07006458 }
6459 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6460 prev_ts = LLONG_MAX;
6461 rst_prev_ts = true;
6462 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006463
Arun Menon906de572013-06-18 17:01:40 -07006464 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6465 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6466 buffer->pPlatformPrivate)->entryList->entry;
6467 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006468 OMX_BUFFERHEADERTYPE *il_buffer;
6469 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6470 if (il_buffer)
6471 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6472 else {
6473 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6474 return OMX_ErrorBadParameter;
6475 }
6476 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
6477 } else {
6478 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006479 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006480
Arun Menon906de572013-06-18 17:01:40 -07006481 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006482}
6483
6484OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006485 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006486{
6487
Arun Menon906de572013-06-18 17:01:40 -07006488 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006489 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006490 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006491 }
6492
6493 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006494 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006495 pending_input_buffers--;
6496
Arun Menon906de572013-06-18 17:01:40 -07006497 if (arbitrary_bytes) {
6498 if (pdest_frame == NULL && input_flush_progress == false) {
6499 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6500 pdest_frame = buffer;
6501 buffer->nFilledLen = 0;
6502 buffer->nTimeStamp = LLONG_MAX;
6503 push_input_buffer (hComp);
6504 } else {
6505 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6506 buffer->nFilledLen = 0;
6507 if (!m_input_free_q.insert_entry((unsigned)buffer,
6508 (unsigned)NULL, (unsigned)NULL)) {
6509 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6510 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006511 }
Arun Menon906de572013-06-18 17:01:40 -07006512 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006513 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006514 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006515 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6516 }
6517 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6518 }
6519 return OMX_ErrorNone;
6520}
6521
Shalaj Jain273b3e02012-06-22 19:08:03 -07006522int omx_vdec::async_message_process (void *context, void* message)
6523{
Arun Menon906de572013-06-18 17:01:40 -07006524 omx_vdec* omx = NULL;
6525 struct vdec_msginfo *vdec_msg = NULL;
6526 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6527 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6528 struct vdec_output_frameinfo *output_respbuf = NULL;
6529 int rc=1;
6530 if (context == NULL || message == NULL) {
6531 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6532 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006533 }
Arun Menon906de572013-06-18 17:01:40 -07006534 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006535
Arun Menon906de572013-06-18 17:01:40 -07006536 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006537
Arun Menon906de572013-06-18 17:01:40 -07006538 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006539
Arun Menon906de572013-06-18 17:01:40 -07006540 case VDEC_MSG_EVT_HW_ERROR:
6541 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6542 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6543 break;
6544
6545 case VDEC_MSG_RESP_START_DONE:
6546 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6547 OMX_COMPONENT_GENERATE_START_DONE);
6548 break;
6549
6550 case VDEC_MSG_RESP_STOP_DONE:
6551 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6552 OMX_COMPONENT_GENERATE_STOP_DONE);
6553 break;
6554
6555 case VDEC_MSG_RESP_RESUME_DONE:
6556 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6557 OMX_COMPONENT_GENERATE_RESUME_DONE);
6558 break;
6559
6560 case VDEC_MSG_RESP_PAUSE_DONE:
6561 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6562 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6563 break;
6564
6565 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6566 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6567 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6568 break;
6569 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6570 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6571 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6572 break;
6573 case VDEC_MSG_RESP_INPUT_FLUSHED:
6574 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6575
6576 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6577 vdec_msg->msgdata.input_frame_clientdata; */
6578
6579 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6580 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6581 if (omxhdr == NULL ||
6582 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) {
6583 omxhdr = NULL;
6584 vdec_msg->status_code = VDEC_S_EFATAL;
6585 }
6586 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6587 DEBUG_PRINT_HIGH("Unsupported input");
6588 omx->omx_report_error ();
6589 }
6590 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6591 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6592 }
6593 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6594 OMX_COMPONENT_GENERATE_EBD);
6595 break;
6596 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6597 int64_t *timestamp;
6598 timestamp = (int64_t *) malloc(sizeof(int64_t));
6599 if (timestamp) {
6600 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6601 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6602 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6603 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6604 vdec_msg->msgdata.output_frame.time_stamp);
6605 }
6606 break;
6607 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6608 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6609
6610 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6611 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6612 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6613 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6614 vdec_msg->msgdata.output_frame.pic_type);
6615
6616 if (omxhdr && omxhdr->pOutputPortPrivate &&
6617 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6618 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6619 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006620#ifdef META_DATA_MODE_SUPPORTED
6621 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6622 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6623 }
6624#endif
Arun Menon906de572013-06-18 17:01:40 -07006625 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6626 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6627 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6628 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6629 omxhdr->nFlags = 0;
6630
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006631 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006632 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6633 //rc = -1;
6634 }
6635 if (omxhdr->nFilledLen) {
6636 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6637 }
6638 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6639 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6640 } else {
6641 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6642 }
6643 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6644 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6645 }
6646 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6647 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6648 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006649#ifdef META_DATA_MODE_SUPPORTED
6650 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
Arun Menone50f6ef2013-09-30 15:08:27 -07006651 omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
Arun Menonbdb80b02013-08-12 17:45:54 -07006652 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6653 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6654 }
6655
6656 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6657 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6658 omxhdr->nOffset);
6659 }
6660#endif
Arun Menon906de572013-06-18 17:01:40 -07006661 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6662 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006663 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006664 omx->time_stamp_dts.remove_time_stamp(
6665 omxhdr->nTimeStamp,
6666 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6667 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006668 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6669 OMX_COMPONENT_GENERATE_FTB);
6670 break;
6671 }
6672 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6673 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6674 }
6675 vdec_msg->msgdata.output_frame.bufferaddr =
6676 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6677 int format_notably_changed = 0;
6678 if (omxhdr->nFilledLen &&
6679 (omxhdr->nFilledLen != omx->prev_n_filled_len)) {
6680 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6681 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6682 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
6683 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6684 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6685 format_notably_changed = 1;
6686 }
6687 }
6688 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6689 vdec_msg->msgdata.output_frame.framesize.left)
6690 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6691 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6692 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6693 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6694 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6695 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6696 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6697 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
6698 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6699 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6700 }
6701 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
6702 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6703 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006704 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6705 omx->drv_ctx.video_resolution.frame_width) {
6706 vdec_msg->msgdata.output_frame.framesize.left = 0;
6707 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6708 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6709 }
6710 }
6711 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6712 omx->drv_ctx.video_resolution.frame_height) {
6713 vdec_msg->msgdata.output_frame.framesize.top = 0;
6714 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6715 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6716 }
6717 }
6718 DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d\n",
6719 vdec_msg->msgdata.output_frame.framesize.left,
6720 vdec_msg->msgdata.output_frame.framesize.top,
6721 vdec_msg->msgdata.output_frame.framesize.right,
6722 vdec_msg->msgdata.output_frame.framesize.bottom,
6723 omx->drv_ctx.video_resolution.frame_width,
6724 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006725 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6726 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6727 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6728 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6729 format_notably_changed = 1;
6730 }
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006731 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d\n",
6732 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6733 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006734 if (format_notably_changed) {
6735 if (omx->is_video_session_supported()) {
6736 omx->post_event (NULL, vdec_msg->status_code,
6737 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6738 } else {
6739 if (!omx->client_buffers.update_buffer_req()) {
6740 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6741 }
6742 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6743 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6744 }
6745 }
6746 if (omxhdr->nFilledLen)
6747 omx->prev_n_filled_len = omxhdr->nFilledLen;
6748
6749 output_respbuf = (struct vdec_output_frameinfo *)\
6750 omxhdr->pOutputPortPrivate;
6751 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6752 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6753 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6754 output_respbuf->pic_type = PICTURE_TYPE_I;
6755 }
6756 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6757 output_respbuf->pic_type = PICTURE_TYPE_P;
6758 }
6759 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6760 output_respbuf->pic_type = PICTURE_TYPE_B;
6761 }
6762
6763 if (omx->output_use_buffer)
6764 memcpy ( omxhdr->pBuffer, (void *)
6765 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6766 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6767 vdec_msg->msgdata.output_frame.len);
6768 } else
6769 omxhdr->nFilledLen = 0;
6770 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6771 OMX_COMPONENT_GENERATE_FBD);
6772 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6773 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6774 OMX_COMPONENT_GENERATE_EOS_DONE);
6775 else
6776 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6777 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6778 break;
6779 case VDEC_MSG_EVT_CONFIG_CHANGED:
6780 DEBUG_PRINT_HIGH("\n Port settings changed");
6781 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6782 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6783 break;
6784 default:
6785 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006786 }
Arun Menon906de572013-06-18 17:01:40 -07006787 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006788}
6789
6790OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006791 OMX_HANDLETYPE hComp,
6792 OMX_BUFFERHEADERTYPE *buffer
6793 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006794{
Arun Menon906de572013-06-18 17:01:40 -07006795 unsigned address,p2,id;
6796 DEBUG_PRINT_LOW("\n Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006797
Arun Menon906de572013-06-18 17:01:40 -07006798 if (buffer == NULL) {
6799 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006800 }
Arun Menon906de572013-06-18 17:01:40 -07006801 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6802 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
6803 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6804
6805 /* return zero length and not an EOS buffer */
6806 /* return buffer if input flush in progress */
6807 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6808 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
6809 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
6810 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6811 return OMX_ErrorNone;
6812 }
6813
6814 if (psource_frame == NULL) {
6815 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
6816 psource_frame = buffer;
6817 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
6818 push_input_buffer (hComp);
6819 } else {
6820 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
6821 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6822 (unsigned)NULL)) {
6823 return OMX_ErrorBadParameter;
6824 }
6825 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006826
6827
Arun Menon906de572013-06-18 17:01:40 -07006828 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006829}
6830
6831OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6832{
Arun Menon906de572013-06-18 17:01:40 -07006833 unsigned address,p2,id;
6834 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006835
Arun Menon906de572013-06-18 17:01:40 -07006836 if (pdest_frame == NULL || psource_frame == NULL) {
6837 /*Check if we have a destination buffer*/
6838 if (pdest_frame == NULL) {
6839 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
6840 if (m_input_free_q.m_size) {
6841 m_input_free_q.pop_entry(&address,&p2,&id);
6842 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6843 pdest_frame->nFilledLen = 0;
6844 pdest_frame->nTimeStamp = LLONG_MAX;
6845 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
6846 }
6847 }
6848
6849 /*Check if we have a destination buffer*/
6850 if (psource_frame == NULL) {
6851 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
6852 if (m_input_pending_q.m_size) {
6853 m_input_pending_q.pop_entry(&address,&p2,&id);
6854 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
6855 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6856 psource_frame->nTimeStamp);
6857 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6858 psource_frame->nFlags,psource_frame->nFilledLen);
6859
6860 }
6861 }
6862
Shalaj Jain273b3e02012-06-22 19:08:03 -07006863 }
6864
Arun Menon906de572013-06-18 17:01:40 -07006865 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6866 switch (codec_type_parse) {
6867 case CODEC_TYPE_MPEG4:
6868 case CODEC_TYPE_H263:
6869 case CODEC_TYPE_MPEG2:
6870 ret = push_input_sc_codec(hComp);
6871 break;
6872 case CODEC_TYPE_H264:
6873 ret = push_input_h264(hComp);
6874 break;
6875 case CODEC_TYPE_VC1:
6876 ret = push_input_vc1(hComp);
6877 break;
6878 default:
6879 break;
6880 }
6881 if (ret != OMX_ErrorNone) {
6882 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
6883 omx_report_error ();
6884 break;
6885 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006886 }
6887
Arun Menon906de572013-06-18 17:01:40 -07006888 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006889}
6890
6891OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
6892{
Arun Menon906de572013-06-18 17:01:40 -07006893 OMX_U32 partial_frame = 1;
6894 OMX_BOOL generate_ebd = OMX_TRUE;
6895 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006896
Arun Menon906de572013-06-18 17:01:40 -07006897 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
6898 psource_frame,psource_frame->nTimeStamp);
6899 if (m_frame_parser.parse_sc_frame(psource_frame,
6900 pdest_frame,&partial_frame) == -1) {
6901 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
6902 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006903 }
Arun Menon906de572013-06-18 17:01:40 -07006904
6905 if (partial_frame == 0) {
6906 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
6907 pdest_frame->nFilledLen,psource_frame,frame_count);
6908
6909
6910 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
6911 /*First Parsed buffer will have only header Hence skip*/
6912 if (frame_count == 0) {
6913 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
6914
6915 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
6916 codec_type_parse == CODEC_TYPE_DIVX) {
6917 mp4StreamType psBits;
6918 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
6919 psBits.numBytes = pdest_frame->nFilledLen;
6920 mp4_headerparser.parseHeader(&psBits);
6921 }
6922
6923 frame_count++;
6924 } else {
6925 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6926 if (pdest_frame->nFilledLen) {
6927 /*Push the frame to the Decoder*/
6928 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6929 return OMX_ErrorBadParameter;
6930 }
6931 frame_count++;
6932 pdest_frame = NULL;
6933
6934 if (m_input_free_q.m_size) {
6935 m_input_free_q.pop_entry(&address,&p2,&id);
6936 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6937 pdest_frame->nFilledLen = 0;
6938 }
6939 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
6940 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
6941 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
6942 (unsigned)NULL);
6943 pdest_frame = NULL;
6944 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006945 }
Arun Menon906de572013-06-18 17:01:40 -07006946 } else {
6947 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
6948 /*Check if Destination Buffer is full*/
6949 if (pdest_frame->nAllocLen ==
6950 pdest_frame->nFilledLen + pdest_frame->nOffset) {
6951 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
6952 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006953 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006954 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006955
Arun Menon906de572013-06-18 17:01:40 -07006956 if (psource_frame->nFilledLen == 0) {
6957 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6958 if (pdest_frame) {
6959 pdest_frame->nFlags |= psource_frame->nFlags;
6960 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
6961 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6962 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6963 pdest_frame->nFilledLen,frame_count++);
6964 /*Push the frame to the Decoder*/
6965 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6966 return OMX_ErrorBadParameter;
6967 }
6968 frame_count++;
6969 pdest_frame = NULL;
6970 } else {
6971 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
6972 generate_ebd = OMX_FALSE;
6973 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006974 }
Arun Menon906de572013-06-18 17:01:40 -07006975 if (generate_ebd) {
6976 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
6977 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6978 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006979
Arun Menon906de572013-06-18 17:01:40 -07006980 if (m_input_pending_q.m_size) {
6981 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6982 m_input_pending_q.pop_entry(&address,&p2,&id);
6983 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6984 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6985 psource_frame->nTimeStamp);
6986 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6987 psource_frame->nFlags,psource_frame->nFilledLen);
6988 }
6989 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006990 }
Arun Menon906de572013-06-18 17:01:40 -07006991 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006992}
6993
6994OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
6995{
Arun Menon906de572013-06-18 17:01:40 -07006996 OMX_U32 partial_frame = 1;
6997 unsigned address = 0, p2 = 0, id = 0;
6998 OMX_BOOL isNewFrame = OMX_FALSE;
6999 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007000
Arun Menon906de572013-06-18 17:01:40 -07007001 if (h264_scratch.pBuffer == NULL) {
7002 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7003 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007004 }
Arun Menon906de572013-06-18 17:01:40 -07007005 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
7006 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
7007 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
7008 if (h264_scratch.nFilledLen && look_ahead_nal) {
7009 look_ahead_nal = false;
7010 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7011 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007012 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7013 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7014 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Arun Menon906de572013-06-18 17:01:40 -07007015 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007016 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07007017 } else {
7018 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007019 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007020 }
Arun Menon906de572013-06-18 17:01:40 -07007021 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07007022
7023 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
7024 in EOS flag getting associated with the destination
7025 */
7026 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
7027 pdest_frame->nFilledLen) {
7028 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
7029 generate_ebd = OMX_FALSE;
7030 }
7031
Arun Menon906de572013-06-18 17:01:40 -07007032 if (nal_length == 0) {
7033 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7034 if (m_frame_parser.parse_sc_frame(psource_frame,
7035 &h264_scratch,&partial_frame) == -1) {
7036 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07007037 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007038 }
Arun Menon906de572013-06-18 17:01:40 -07007039 } else {
7040 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7041 if (m_frame_parser.parse_h264_nallength(psource_frame,
7042 &h264_scratch,&partial_frame) == -1) {
7043 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7044 return OMX_ErrorBadParameter;
7045 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007046 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007047
Arun Menon906de572013-06-18 17:01:40 -07007048 if (partial_frame == 0) {
7049 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
7050 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7051 nal_count++;
7052 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7053 h264_scratch.nFlags = psource_frame->nFlags;
7054 } else {
7055 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
7056 if (h264_scratch.nFilledLen) {
7057 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7058 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007059#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007060 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7061 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7062 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7063 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7064 // If timeinfo is present frame info from SEI is already processed
7065 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7066 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007067#endif
Arun Menon906de572013-06-18 17:01:40 -07007068 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7069 nal_count++;
7070 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7071 pdest_frame->nTimeStamp = h264_last_au_ts;
7072 pdest_frame->nFlags = h264_last_au_flags;
7073#ifdef PANSCAN_HDLR
7074 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7075 h264_parser->update_panscan_data(h264_last_au_ts);
7076#endif
7077 }
7078 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7079 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7080 h264_last_au_ts = h264_scratch.nTimeStamp;
7081 h264_last_au_flags = h264_scratch.nFlags;
7082#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7083 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7084 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7085 if (!VALID_TS(h264_last_au_ts))
7086 h264_last_au_ts = ts_in_sei;
7087 }
7088#endif
7089 } else
7090 h264_last_au_ts = LLONG_MAX;
7091 }
7092
7093 if (!isNewFrame) {
7094 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7095 h264_scratch.nFilledLen) {
7096 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
7097 h264_scratch.nFilledLen);
7098 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7099 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7100 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7101 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7102 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7103 h264_scratch.nFilledLen = 0;
7104 } else {
7105 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7106 return OMX_ErrorBadParameter;
7107 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007108 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007109 look_ahead_nal = true;
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05307110 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007111 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7112 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
7113 pdest_frame->nFilledLen,frame_count++);
7114
7115 if (pdest_frame->nFilledLen == 0) {
7116 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7117 look_ahead_nal = false;
7118 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7119 h264_scratch.nFilledLen) {
7120 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7121 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7122 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7123 h264_scratch.nFilledLen = 0;
7124 } else {
7125 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7126 return OMX_ErrorBadParameter;
7127 }
7128 } else {
7129 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
7130 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7131 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7132 }
7133 /*Push the frame to the Decoder*/
7134 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7135 return OMX_ErrorBadParameter;
7136 }
7137 //frame_count++;
7138 pdest_frame = NULL;
7139 if (m_input_free_q.m_size) {
7140 m_input_free_q.pop_entry(&address,&p2,&id);
7141 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7142 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7143 pdest_frame->nFilledLen = 0;
7144 pdest_frame->nFlags = 0;
7145 pdest_frame->nTimeStamp = LLONG_MAX;
7146 }
7147 }
7148 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007149 }
Arun Menon906de572013-06-18 17:01:40 -07007150 } else {
7151 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
7152 /*Check if Destination Buffer is full*/
7153 if (h264_scratch.nAllocLen ==
7154 h264_scratch.nFilledLen + h264_scratch.nOffset) {
7155 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7156 return OMX_ErrorStreamCorrupt;
7157 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007158 }
Arun Menon906de572013-06-18 17:01:40 -07007159
7160 if (!psource_frame->nFilledLen) {
7161 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7162
7163 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7164 if (pdest_frame) {
7165 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7166 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7167 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007168 if(pdest_frame->nFilledLen == 0) {
7169 /* No residual frame from before, send whatever
7170 * we have left */
7171 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7172 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7173 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7174 h264_scratch.nFilledLen = 0;
7175 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7176 } else {
7177 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7178 if(!isNewFrame) {
7179 /* Have a residual frame, but we know that the
7180 * AU in this frame is belonging to whatever
7181 * frame we had left over. So append it */
7182 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7183 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7184 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7185 h264_scratch.nFilledLen = 0;
7186 pdest_frame->nTimeStamp = h264_last_au_ts;
7187 } else {
7188 /* Completely new frame, let's just push what
7189 * we have now. The resulting EBD would trigger
7190 * another push */
7191 generate_ebd = OMX_FALSE;
7192 pdest_frame->nTimeStamp = h264_last_au_ts;
7193 h264_last_au_ts = h264_scratch.nTimeStamp;
7194 }
7195 }
Arun Menon906de572013-06-18 17:01:40 -07007196 } else {
7197 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7198 return OMX_ErrorBadParameter;
7199 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007200
7201 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7202 if(generate_ebd == OMX_TRUE) {
7203 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7204 }
Arun Menon906de572013-06-18 17:01:40 -07007205
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05307206 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007207 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7208 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7209#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7210 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7211 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7212 if (!VALID_TS(pdest_frame->nTimeStamp))
7213 pdest_frame->nTimeStamp = ts_in_sei;
7214 }
7215#endif
7216 /*Push the frame to the Decoder*/
7217 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7218 return OMX_ErrorBadParameter;
7219 }
7220 frame_count++;
7221 pdest_frame = NULL;
7222 } else {
7223 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
7224 pdest_frame,h264_scratch.nFilledLen);
7225 generate_ebd = OMX_FALSE;
7226 }
7227 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007228 }
Arun Menon906de572013-06-18 17:01:40 -07007229 if (generate_ebd && !psource_frame->nFilledLen) {
7230 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7231 psource_frame = NULL;
7232 if (m_input_pending_q.m_size) {
7233 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7234 m_input_pending_q.pop_entry(&address,&p2,&id);
7235 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7236 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
7237 psource_frame->nFlags,psource_frame->nFilledLen);
7238 }
7239 }
7240 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007241}
7242
7243OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7244{
7245 OMX_U8 *buf, *pdest;
7246 OMX_U32 partial_frame = 1;
7247 OMX_U32 buf_len, dest_len;
7248
Arun Menon906de572013-06-18 17:01:40 -07007249 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007250 first_frame = 1;
7251 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
Arun Menon906de572013-06-18 17:01:40 -07007252 if (!m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007253 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7254 buf = psource_frame->pBuffer;
7255 buf_len = psource_frame->nFilledLen;
7256
7257 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007258 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007259 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007260 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007261 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007262 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007263 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7264 return OMX_ErrorStreamCorrupt;
7265 }
Arun Menon906de572013-06-18 17:01:40 -07007266 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007267 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7268 pdest_frame->nOffset;
7269 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007270 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007271
Arun Menon906de572013-06-18 17:01:40 -07007272 if (dest_len < m_vendor_config.nDataSize) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007273 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7274 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007275 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007276 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7277 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7278 }
7279 }
7280 }
7281
Arun Menon906de572013-06-18 17:01:40 -07007282 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007283 case VC1_AP:
7284 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007285 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007286 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7287 return OMX_ErrorBadParameter;
7288 }
Arun Menon906de572013-06-18 17:01:40 -07007289 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007290
7291 case VC1_SP_MP_RCV:
7292 default:
7293 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7294 return OMX_ErrorBadParameter;
7295 }
7296 return OMX_ErrorNone;
7297}
7298
David Ng38e2d232013-03-15 20:05:58 -07007299#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007300bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007301 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007302{
Arun Menon906de572013-06-18 17:01:40 -07007303 struct pmem_allocation allocation;
7304 allocation.size = buffer_size;
7305 allocation.align = clip2(alignment);
7306 if (allocation.align < 4096) {
7307 allocation.align = 4096;
7308 }
7309 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
7310 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7311 allocation.align, allocation.size);
7312 return false;
7313 }
7314 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007315}
David Ng38e2d232013-03-15 20:05:58 -07007316#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007317#ifdef USE_ION
7318int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007319 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7320 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007321{
Arun Menon906de572013-06-18 17:01:40 -07007322 int fd = -EINVAL;
7323 int rc = -EINVAL;
7324 int ion_dev_flag;
7325 struct vdec_ion ion_buf_info;
7326 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7327 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7328 return -EINVAL;
7329 }
7330 ion_dev_flag = O_RDONLY;
7331 fd = open (MEM_DEVICE, ion_dev_flag);
7332 if (fd < 0) {
7333 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7334 return fd;
7335 }
7336 alloc_data->flags = 0;
7337 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7338 alloc_data->flags |= ION_FLAG_CACHED;
7339 }
7340 alloc_data->len = buffer_size;
7341 alloc_data->align = clip2(alignment);
7342 if (alloc_data->align < 4096) {
7343 alloc_data->align = 4096;
7344 }
7345 if ((secure_mode) && (flag & ION_SECURE))
7346 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007347
Arun Menon906de572013-06-18 17:01:40 -07007348 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7349 if (secure_mode)
7350 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7351 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7352 if (rc || !alloc_data->handle) {
7353 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7354 alloc_data->handle = NULL;
7355 close(fd);
7356 fd = -ENOMEM;
7357 return fd;
7358 }
7359 fd_data->handle = alloc_data->handle;
7360 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7361 if (rc) {
7362 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7363 ion_buf_info.ion_alloc_data = *alloc_data;
7364 ion_buf_info.ion_device_fd = fd;
7365 ion_buf_info.fd_ion_data = *fd_data;
7366 free_ion_memory(&ion_buf_info);
7367 fd_data->fd =-1;
7368 close(fd);
7369 fd = -ENOMEM;
7370 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007371
Arun Menon906de572013-06-18 17:01:40 -07007372 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007373}
7374
Arun Menon906de572013-06-18 17:01:40 -07007375void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7376{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007377
Arun Menon906de572013-06-18 17:01:40 -07007378 if (!buf_ion_info) {
7379 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7380 return;
7381 }
7382 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7383 &buf_ion_info->ion_alloc_data.handle)) {
7384 DEBUG_PRINT_ERROR("\n ION: free failed" );
7385 }
7386 close(buf_ion_info->ion_device_fd);
7387 buf_ion_info->ion_device_fd = -1;
7388 buf_ion_info->ion_alloc_data.handle = NULL;
7389 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007390}
7391#endif
7392void omx_vdec::free_output_buffer_header()
7393{
Arun Menon906de572013-06-18 17:01:40 -07007394 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7395 output_use_buffer = false;
7396 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007397
Arun Menon906de572013-06-18 17:01:40 -07007398 if (m_out_mem_ptr) {
7399 free (m_out_mem_ptr);
7400 m_out_mem_ptr = NULL;
7401 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007402
Arun Menon906de572013-06-18 17:01:40 -07007403 if (m_platform_list) {
7404 free(m_platform_list);
7405 m_platform_list = NULL;
7406 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007407
Arun Menon906de572013-06-18 17:01:40 -07007408 if (drv_ctx.ptr_respbuffer) {
7409 free (drv_ctx.ptr_respbuffer);
7410 drv_ctx.ptr_respbuffer = NULL;
7411 }
7412 if (drv_ctx.ptr_outputbuffer) {
7413 free (drv_ctx.ptr_outputbuffer);
7414 drv_ctx.ptr_outputbuffer = NULL;
7415 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007416#ifdef USE_ION
7417 if (drv_ctx.op_buf_ion_info) {
7418 DEBUG_PRINT_LOW("\n Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007419 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007420 drv_ctx.op_buf_ion_info = NULL;
7421 }
7422#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007423#ifdef META_DATA_MODE_SUPPORTED
7424 if (out_dynamic_list) {
7425 free(out_dynamic_list);
7426 out_dynamic_list = NULL;
7427 }
7428#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007429}
7430
7431void omx_vdec::free_input_buffer_header()
7432{
7433 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007434 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007435 if (m_inp_heap_ptr) {
7436 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7437 free (m_inp_heap_ptr);
7438 m_inp_heap_ptr = NULL;
7439 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007440
Arun Menon906de572013-06-18 17:01:40 -07007441 if (m_phdr_pmem_ptr) {
7442 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7443 free (m_phdr_pmem_ptr);
7444 m_phdr_pmem_ptr = NULL;
7445 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007446 }
Arun Menon906de572013-06-18 17:01:40 -07007447 if (m_inp_mem_ptr) {
7448 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7449 free (m_inp_mem_ptr);
7450 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007451 }
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007452 /* We just freed all the buffer headers, every thing in m_input_free_q
7453 * is now invalid */
7454 while (m_input_free_q.m_size) {
7455 unsigned address, p2, id;
7456 m_input_free_q.pop_entry(&address, &p2, &id);
7457 }
Arun Menon906de572013-06-18 17:01:40 -07007458 if (drv_ctx.ptr_inputbuffer) {
7459 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7460 free (drv_ctx.ptr_inputbuffer);
7461 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007462 }
7463#ifdef USE_ION
7464 if (drv_ctx.ip_buf_ion_info) {
7465 DEBUG_PRINT_LOW("\n Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007466 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007467 drv_ctx.ip_buf_ion_info = NULL;
7468 }
7469#endif
7470}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007471
7472int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007473{
Arun Menon906de572013-06-18 17:01:40 -07007474 enum v4l2_buf_type btype;
7475 int rc = 0;
7476 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007477
Arun Menon906de572013-06-18 17:01:40 -07007478 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7479 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7480 v4l2_port = OUTPUT_PORT;
7481 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7482 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7483 v4l2_port = CAPTURE_PORT;
7484 } else if (port == OMX_ALL) {
7485 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7486 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007487
Arun Menon906de572013-06-18 17:01:40 -07007488 if (!rc_input)
7489 return rc_input;
7490 else
7491 return rc_output;
7492 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007493
Arun Menon906de572013-06-18 17:01:40 -07007494 if (!streaming[v4l2_port]) {
7495 // already streamed off, warn and move on
7496 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7497 " which is already streamed off", v4l2_port);
7498 return 0;
7499 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007500
Arun Menon906de572013-06-18 17:01:40 -07007501 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007502
Arun Menon906de572013-06-18 17:01:40 -07007503 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7504 if (rc) {
7505 /*TODO: How to handle this case */
7506 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
7507 } else {
7508 streaming[v4l2_port] = false;
7509 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007510
Arun Menon906de572013-06-18 17:01:40 -07007511 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007512}
7513
7514OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7515{
Arun Menon906de572013-06-18 17:01:40 -07007516 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7517 struct v4l2_requestbuffers bufreq;
7518 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7519 struct v4l2_format fmt;
7520 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007521 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007522 buffer_prop->actualcount, buffer_prop->buffer_size);
7523 bufreq.memory = V4L2_MEMORY_USERPTR;
7524 bufreq.count = 1;
7525 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7526 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7527 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7528 fmt.fmt.pix_mp.pixelformat = output_capability;
7529 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7530 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7531 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7532 fmt.fmt.pix_mp.pixelformat = capture_capability;
7533 } else {
7534 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007535 }
Arun Menon906de572013-06-18 17:01:40 -07007536 if (eRet==OMX_ErrorNone) {
7537 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007538 }
Arun Menon906de572013-06-18 17:01:40 -07007539 if (ret) {
7540 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7541 /*TODO: How to handle this case */
7542 eRet = OMX_ErrorInsufficientResources;
7543 return eRet;
7544 } else {
7545 buffer_prop->actualcount = bufreq.count;
7546 buffer_prop->mincount = bufreq.count;
7547 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007548 }
Arun Menon906de572013-06-18 17:01:40 -07007549 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7550 buffer_prop->actualcount, buffer_prop->buffer_size);
7551
7552 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7553 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7554
7555 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7556
7557 update_resolution(fmt.fmt.pix_mp.width,
7558 fmt.fmt.pix_mp.height,
7559 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7560 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7561 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7562 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
7563 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
7564
7565 if (ret) {
7566 /*TODO: How to handle this case */
7567 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7568 eRet = OMX_ErrorInsufficientResources;
7569 } else {
7570 int extra_idx = 0;
7571
7572 eRet = is_video_session_supported();
7573 if (eRet)
7574 return eRet;
7575
7576 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7577 buf_size = buffer_prop->buffer_size;
7578 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7579 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7580 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7581 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7582 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7583 return OMX_ErrorBadParameter;
7584 }
7585 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7586 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7587 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7588 }
7589 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7590 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7591 }
7592 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7593 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7594 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7595 client_extra_data_size);
7596 }
7597 if (client_extra_data_size) {
7598 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7599 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7600 }
7601 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7602 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7603 drv_ctx.extradata_info.buffer_size = extra_data_size;
7604 buf_size += client_extra_data_size;
7605 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7606 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7607 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7608 if (in_reconfig) // BufReq will be set to driver when port is disabled
7609 buffer_prop->buffer_size = buf_size;
7610 else if (buf_size != buffer_prop->buffer_size) {
7611 buffer_prop->buffer_size = buf_size;
7612 eRet = set_buffer_req(buffer_prop);
7613 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007614 }
Arun Menon906de572013-06-18 17:01:40 -07007615 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7616 buffer_prop->actualcount, buffer_prop->buffer_size);
7617 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007618}
7619
7620OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7621{
Arun Menon906de572013-06-18 17:01:40 -07007622 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7623 unsigned buf_size = 0;
7624 struct v4l2_format fmt;
7625 struct v4l2_requestbuffers bufreq;
7626 int ret;
7627 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7628 buffer_prop->actualcount, buffer_prop->buffer_size);
7629 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7630 if (buf_size != buffer_prop->buffer_size) {
7631 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7632 buffer_prop->buffer_size, buf_size);
7633 eRet = OMX_ErrorBadParameter;
7634 } else {
7635 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7636 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007637
Arun Menon906de572013-06-18 17:01:40 -07007638 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7639 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7640 fmt.fmt.pix_mp.pixelformat = output_capability;
7641 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7642 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7643 fmt.fmt.pix_mp.pixelformat = capture_capability;
7644 } else {
7645 eRet = OMX_ErrorBadParameter;
7646 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007647
Arun Menon906de572013-06-18 17:01:40 -07007648 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7649 if (ret) {
7650 /*TODO: How to handle this case */
7651 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7652 eRet = OMX_ErrorInsufficientResources;
7653 }
7654
7655 bufreq.memory = V4L2_MEMORY_USERPTR;
7656 bufreq.count = buffer_prop->actualcount;
7657 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7658 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7659 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7660 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7661 } else {
7662 eRet = OMX_ErrorBadParameter;
7663 }
7664
7665 if (eRet==OMX_ErrorNone) {
7666 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7667 }
7668
7669 if (ret) {
7670 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7671 /*TODO: How to handle this case */
7672 eRet = OMX_ErrorInsufficientResources;
7673 } else if (bufreq.count < buffer_prop->actualcount) {
7674 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7675 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7676 buffer_prop->actualcount, bufreq.count);
7677 eRet = OMX_ErrorInsufficientResources;
7678 } else {
7679 if (!client_buffers.update_buffer_req()) {
7680 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7681 eRet = OMX_ErrorInsufficientResources;
7682 }
7683 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007684 }
Arun Menon906de572013-06-18 17:01:40 -07007685 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007686}
7687
Shalaj Jain273b3e02012-06-22 19:08:03 -07007688OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7689{
Arun Menon906de572013-06-18 17:01:40 -07007690 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7691 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007692}
7693
7694OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7695{
Arun Menon906de572013-06-18 17:01:40 -07007696 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7697 if (!portDefn) {
7698 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007699 }
Arun Menon906de572013-06-18 17:01:40 -07007700 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
7701 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7702 portDefn->nSize = sizeof(portDefn);
7703 portDefn->eDomain = OMX_PortDomainVideo;
7704 if (drv_ctx.frame_rate.fps_denominator > 0)
7705 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7706 drv_ctx.frame_rate.fps_denominator;
7707 else {
7708 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7709 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007710 }
Arun Menon906de572013-06-18 17:01:40 -07007711 if (0 == portDefn->nPortIndex) {
7712 portDefn->eDir = OMX_DirInput;
7713 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7714 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7715 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7716 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7717 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7718 portDefn->bEnabled = m_inp_bEnabled;
7719 portDefn->bPopulated = m_inp_bPopulated;
7720 } else if (1 == portDefn->nPortIndex) {
7721 unsigned int buf_size = 0;
7722 if (!client_buffers.update_buffer_req()) {
7723 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
7724 return OMX_ErrorHardware;
7725 }
7726 if (!client_buffers.get_buffer_req(buf_size)) {
7727 DEBUG_PRINT_ERROR("\n update buffer requirements");
7728 return OMX_ErrorHardware;
7729 }
7730 portDefn->nBufferSize = buf_size;
7731 portDefn->eDir = OMX_DirOutput;
7732 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7733 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7734 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7735 portDefn->bEnabled = m_out_bEnabled;
7736 portDefn->bPopulated = m_out_bPopulated;
7737 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
7738 DEBUG_PRINT_ERROR("\n Error in getting color format");
7739 return OMX_ErrorHardware;
7740 }
7741 } else {
7742 portDefn->eDir = OMX_DirMax;
7743 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7744 (int)portDefn->nPortIndex);
7745 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007746 }
Arun Menon906de572013-06-18 17:01:40 -07007747 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7748 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7749 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7750 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7751 DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
7752 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
7753 portDefn->format.video.nFrameHeight,
7754 portDefn->format.video.nStride,
7755 portDefn->format.video.nSliceHeight);
7756 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007757
7758}
7759
7760OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7761{
Arun Menon906de572013-06-18 17:01:40 -07007762 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7763 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7764 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007765
Arun Menon906de572013-06-18 17:01:40 -07007766 if (!m_out_mem_ptr) {
7767 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
7768 int nBufHdrSize = 0;
7769 int nPlatformEntrySize = 0;
7770 int nPlatformListSize = 0;
7771 int nPMEMInfoSize = 0;
7772 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7773 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7774 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007775
Arun Menon906de572013-06-18 17:01:40 -07007776 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
7777 drv_ctx.op_buf.actualcount);
7778 nBufHdrSize = drv_ctx.op_buf.actualcount *
7779 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007780
Arun Menon906de572013-06-18 17:01:40 -07007781 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7782 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7783 nPlatformListSize = drv_ctx.op_buf.actualcount *
7784 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7785 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7786 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007787
Arun Menon906de572013-06-18 17:01:40 -07007788 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
7789 sizeof(OMX_BUFFERHEADERTYPE),
7790 nPMEMInfoSize,
7791 nPlatformListSize);
7792 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
7793 m_out_bm_count);
7794 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7795 // Alloc mem for platform specific info
7796 char *pPtr=NULL;
7797 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7798 nPMEMInfoSize,1);
7799 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7800 calloc (sizeof(struct vdec_bufferpayload),
7801 drv_ctx.op_buf.actualcount);
7802 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7803 calloc (sizeof (struct vdec_output_frameinfo),
7804 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007805#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007806 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7807 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007808#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007809#ifdef META_DATA_MODE_SUPPORTED
7810 if (dynamic_buf_mode) {
7811 out_dynamic_list = (struct dynamic_buf_list *) \
7812 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
7813 }
7814#endif
Arun Menon906de572013-06-18 17:01:40 -07007815 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7816 && drv_ctx.ptr_respbuffer) {
7817 bufHdr = m_out_mem_ptr;
7818 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7819 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7820 (((char *) m_platform_list) + nPlatformListSize);
7821 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7822 (((char *) m_platform_entry) + nPlatformEntrySize);
7823 pPlatformList = m_platform_list;
7824 pPlatformEntry = m_platform_entry;
7825 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007826
Arun Menon906de572013-06-18 17:01:40 -07007827 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007828
Arun Menon906de572013-06-18 17:01:40 -07007829 // Settting the entire storage nicely
7830 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
7831 m_out_mem_ptr,pPlatformEntry);
7832 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
7833 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7834 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7835 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7836 // Set the values when we determine the right HxW param
7837 bufHdr->nAllocLen = 0;
7838 bufHdr->nFilledLen = 0;
7839 bufHdr->pAppPrivate = NULL;
7840 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7841 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7842 pPlatformEntry->entry = pPMEMInfo;
7843 // Initialize the Platform List
7844 pPlatformList->nEntries = 1;
7845 pPlatformList->entryList = pPlatformEntry;
7846 // Keep pBuffer NULL till vdec is opened
7847 bufHdr->pBuffer = NULL;
7848 pPMEMInfo->offset = 0;
7849 pPMEMInfo->pmem_fd = 0;
7850 bufHdr->pPlatformPrivate = pPlatformList;
7851 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007852#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007853 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007854#endif
Arun Menon906de572013-06-18 17:01:40 -07007855 /*Create a mapping between buffers*/
7856 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7857 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7858 &drv_ctx.ptr_outputbuffer[i];
7859 // Move the buffer and buffer header pointers
7860 bufHdr++;
7861 pPMEMInfo++;
7862 pPlatformEntry++;
7863 pPlatformList++;
7864 }
7865 } else {
7866 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
7867 m_out_mem_ptr, pPtr);
7868 if (m_out_mem_ptr) {
7869 free(m_out_mem_ptr);
7870 m_out_mem_ptr = NULL;
7871 }
7872 if (pPtr) {
7873 free(pPtr);
7874 pPtr = NULL;
7875 }
7876 if (drv_ctx.ptr_outputbuffer) {
7877 free(drv_ctx.ptr_outputbuffer);
7878 drv_ctx.ptr_outputbuffer = NULL;
7879 }
7880 if (drv_ctx.ptr_respbuffer) {
7881 free(drv_ctx.ptr_respbuffer);
7882 drv_ctx.ptr_respbuffer = NULL;
7883 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007884#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007885 if (drv_ctx.op_buf_ion_info) {
7886 DEBUG_PRINT_LOW("\n Free o/p ion context");
7887 free(drv_ctx.op_buf_ion_info);
7888 drv_ctx.op_buf_ion_info = NULL;
7889 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007890#endif
Arun Menon906de572013-06-18 17:01:40 -07007891 eRet = OMX_ErrorInsufficientResources;
7892 }
7893 } else {
7894 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007895 }
Arun Menon906de572013-06-18 17:01:40 -07007896 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007897}
7898
7899void omx_vdec::complete_pending_buffer_done_cbs()
7900{
Arun Menon906de572013-06-18 17:01:40 -07007901 unsigned p1;
7902 unsigned p2;
7903 unsigned ident;
7904 omx_cmd_queue tmp_q, pending_bd_q;
7905 pthread_mutex_lock(&m_lock);
7906 // pop all pending GENERATE FDB from ftb queue
7907 while (m_ftb_q.m_size) {
7908 m_ftb_q.pop_entry(&p1,&p2,&ident);
7909 if (ident == OMX_COMPONENT_GENERATE_FBD) {
7910 pending_bd_q.insert_entry(p1,p2,ident);
7911 } else {
7912 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007913 }
Arun Menon906de572013-06-18 17:01:40 -07007914 }
7915 //return all non GENERATE FDB to ftb queue
7916 while (tmp_q.m_size) {
7917 tmp_q.pop_entry(&p1,&p2,&ident);
7918 m_ftb_q.insert_entry(p1,p2,ident);
7919 }
7920 // pop all pending GENERATE EDB from etb queue
7921 while (m_etb_q.m_size) {
7922 m_etb_q.pop_entry(&p1,&p2,&ident);
7923 if (ident == OMX_COMPONENT_GENERATE_EBD) {
7924 pending_bd_q.insert_entry(p1,p2,ident);
7925 } else {
7926 tmp_q.insert_entry(p1,p2,ident);
7927 }
7928 }
7929 //return all non GENERATE FDB to etb queue
7930 while (tmp_q.m_size) {
7931 tmp_q.pop_entry(&p1,&p2,&ident);
7932 m_etb_q.insert_entry(p1,p2,ident);
7933 }
7934 pthread_mutex_unlock(&m_lock);
7935 // process all pending buffer dones
7936 while (pending_bd_q.m_size) {
7937 pending_bd_q.pop_entry(&p1,&p2,&ident);
7938 switch (ident) {
7939 case OMX_COMPONENT_GENERATE_EBD:
7940 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
7941 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
7942 omx_report_error ();
7943 }
7944 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007945
Arun Menon906de572013-06-18 17:01:40 -07007946 case OMX_COMPONENT_GENERATE_FBD:
7947 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
7948 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
7949 omx_report_error ();
7950 }
7951 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007952 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007953 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007954}
7955
7956void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
7957{
Arun Menon906de572013-06-18 17:01:40 -07007958 OMX_U32 new_frame_interval = 0;
7959 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
7960 && llabs(act_timestamp - prev_ts) > 2000) {
7961 new_frame_interval = client_set_fps ? frm_int :
7962 llabs(act_timestamp - prev_ts);
7963 if (new_frame_interval < frm_int || frm_int == 0) {
7964 frm_int = new_frame_interval;
7965 if (frm_int) {
7966 drv_ctx.frame_rate.fps_numerator = 1e6;
7967 drv_ctx.frame_rate.fps_denominator = frm_int;
7968 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
7969 frm_int, drv_ctx.frame_rate.fps_numerator /
7970 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007971
Arun Menon906de572013-06-18 17:01:40 -07007972 /* We need to report the difference between this FBD and the previous FBD
7973 * back to the driver for clock scaling purposes. */
7974 struct v4l2_outputparm oparm;
7975 /*XXX: we're providing timing info as seconds per frame rather than frames
7976 * per second.*/
7977 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
7978 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007979
Arun Menon906de572013-06-18 17:01:40 -07007980 struct v4l2_streamparm sparm;
7981 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7982 sparm.parm.output = oparm;
7983 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
7984 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
7985 performance might be affected");
7986 }
7987
7988 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007989 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007990 }
Arun Menon906de572013-06-18 17:01:40 -07007991 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007992}
7993
7994void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
7995{
Arun Menon906de572013-06-18 17:01:40 -07007996 if (rst_prev_ts && VALID_TS(act_timestamp)) {
7997 prev_ts = act_timestamp;
7998 rst_prev_ts = false;
7999 } else if (VALID_TS(prev_ts)) {
8000 bool codec_cond = (drv_ctx.timestamp_adjust)?
8001 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8002 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8003 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8004 if (frm_int > 0 && codec_cond) {
8005 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8006 act_timestamp = prev_ts + frm_int;
8007 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8008 prev_ts = act_timestamp;
8009 } else
8010 set_frame_rate(act_timestamp);
8011 } else if (frm_int > 0) // In this case the frame rate was set along
8012 { // with the port definition, start ts with 0
8013 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8014 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008015 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008016}
8017
8018void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8019{
Arun Menon906de572013-06-18 17:01:40 -07008020 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8021 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308022 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07008023 OMX_U32 frame_rate = 0;
8024 int consumed_len = 0;
8025 OMX_U32 num_MB_in_frame;
8026 OMX_U32 recovery_sei_flags = 1;
8027 int enable = 0;
8028 OMX_U32 mbaff = 0;
8029 int buf_index = p_buf_hdr - m_out_mem_ptr;
8030 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
8031 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8032 p_buf_hdr->nOffset;
8033 if (!drv_ctx.extradata_info.uaddr) {
8034 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008035 }
Arun Menon906de572013-06-18 17:01:40 -07008036 p_extra = (OMX_OTHER_EXTRADATATYPE *)
8037 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8038 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8039 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
8040 p_extra = NULL;
8041 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
8042 if (data) {
8043 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
8044 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
8045 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
8046 DEBUG_PRINT_LOW("Invalid extra data size");
8047 break;
8048 }
8049 switch ((unsigned long)data->eType) {
8050 case EXTRADATA_INTERLACE_VIDEO:
8051 struct msm_vidc_interlace_payload *payload;
8052 payload = (struct msm_vidc_interlace_payload *)data->data;
8053 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8054 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8055 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8056 else {
8057 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8058 enable = 1;
8059 }
8060 if (m_enable_android_native_buffers)
8061 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8062 PP_PARAM_INTERLACED, (void*)&enable);
8063 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8064 append_interlace_extradata(p_extra, payload->format);
8065 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8066 }
8067 break;
8068 case EXTRADATA_FRAME_RATE:
8069 struct msm_vidc_framerate_payload *frame_rate_payload;
8070 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8071 frame_rate = frame_rate_payload->frame_rate;
8072 break;
8073 case EXTRADATA_TIMESTAMP:
8074 struct msm_vidc_ts_payload *time_stamp_payload;
8075 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308076 time_stamp = time_stamp_payload->timestamp_lo;
8077 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8078 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008079 break;
8080 case EXTRADATA_NUM_CONCEALED_MB:
8081 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8082 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8083 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8084 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8085 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8086 break;
8087 case EXTRADATA_INDEX:
8088 int *etype;
8089 etype = (int *)(data->data);
8090 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8091 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8092 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8093 if (aspect_ratio_payload) {
8094 ((struct vdec_output_frameinfo *)
8095 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8096 ((struct vdec_output_frameinfo *)
8097 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8098 }
8099 }
8100 break;
8101 case EXTRADATA_RECOVERY_POINT_SEI:
8102 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8103 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8104 recovery_sei_flags = recovery_sei_payload->flags;
8105 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8106 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
8107 DEBUG_PRINT_HIGH("\n");
8108 DEBUG_PRINT_HIGH("***************************************************\n");
8109 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
8110 DEBUG_PRINT_HIGH("***************************************************\n");
8111 }
8112 break;
8113 case EXTRADATA_PANSCAN_WINDOW:
8114 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8115 break;
8116 case EXTRADATA_MPEG2_SEQDISP:
8117 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8118 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8119 if (seqdisp_payload) {
8120 m_disp_hor_size = seqdisp_payload->disp_width;
8121 m_disp_vert_size = seqdisp_payload->disp_height;
8122 }
8123 break;
8124 default:
8125 goto unrecognized_extradata;
8126 }
8127 consumed_len += data->nSize;
8128 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8129 }
8130 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8131 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8132 append_frame_info_extradata(p_extra,
8133 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308134 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008135 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
8136 }
8137 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008138unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07008139 if (!secure_mode && client_extradata)
8140 append_terminator_extradata(p_extra);
8141 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008142}
8143
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008144OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008145 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008146{
Arun Menon906de572013-06-18 17:01:40 -07008147 OMX_ERRORTYPE ret = OMX_ErrorNone;
8148 struct v4l2_control control;
8149 if (m_state != OMX_StateLoaded) {
8150 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8151 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008152 }
Arun Menon906de572013-06-18 17:01:40 -07008153 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
8154 client_extradata, requested_extradata, enable, is_internal);
8155
8156 if (!is_internal) {
8157 if (enable)
8158 client_extradata |= requested_extradata;
8159 else
8160 client_extradata = client_extradata & ~requested_extradata;
8161 }
8162
8163 if (enable) {
8164 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8165 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8166 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8167 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8168 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8169 " Quality of interlaced clips might be impacted.\n");
8170 }
8171 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
8172 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8173 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8174 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8175 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8176 }
8177 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8178 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8179 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8180 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8181 }
8182 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8183 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8184 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8185 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8186 }
8187 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8188 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8189 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8190 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8191 }
8192 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8193 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8194 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8195 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8196 }
8197 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8198 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8199 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8200 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8201 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8202 }
8203 }
8204 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
8205 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8206 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8207 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8208 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8209 }
8210 }
8211 }
8212 ret = get_buffer_req(&drv_ctx.op_buf);
8213 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008214}
8215
8216OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8217{
Arun Menon906de572013-06-18 17:01:40 -07008218 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8219 OMX_U8 *data_ptr = extra->data, data = 0;
8220 while (byte_count < extra->nDataSize) {
8221 data = *data_ptr;
8222 while (data) {
8223 num_MB += (data&0x01);
8224 data >>= 1;
8225 }
8226 data_ptr++;
8227 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008228 }
Arun Menon906de572013-06-18 17:01:40 -07008229 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8230 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8231 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008232}
8233
8234void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8235{
Arun Menon906de572013-06-18 17:01:40 -07008236 if (!m_debug_extradata)
8237 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008238
8239 DEBUG_PRINT_HIGH(
Arun Menon906de572013-06-18 17:01:40 -07008240 "============== Extra Data ==============\n"
8241 " Size: %lu \n"
8242 " Version: %lu \n"
8243 " PortIndex: %lu \n"
8244 " Type: %x \n"
8245 " DataSize: %lu \n",
8246 extra->nSize, extra->nVersion.nVersion,
8247 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008248
Arun Menon906de572013-06-18 17:01:40 -07008249 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8250 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8251 DEBUG_PRINT_HIGH(
8252 "------ Interlace Format ------\n"
8253 " Size: %lu \n"
8254 " Version: %lu \n"
8255 " PortIndex: %lu \n"
8256 " Is Interlace Format: %d \n"
8257 " Interlace Formats: %lu \n"
8258 "=========== End of Interlace ===========\n",
8259 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8260 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8261 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8262 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8263
8264 DEBUG_PRINT_HIGH(
8265 "-------- Frame Format --------\n"
8266 " Picture Type: %d \n"
8267 " Interlace Type: %d \n"
8268 " Pan Scan Total Frame Num: %lu \n"
8269 " Concealed Macro Blocks: %lu \n"
8270 " frame rate: %lu \n"
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05308271 " Time Stamp: %llu \n"
Arun Menon906de572013-06-18 17:01:40 -07008272 " Aspect Ratio X: %lu \n"
8273 " Aspect Ratio Y: %lu \n",
8274 fminfo->ePicType,
8275 fminfo->interlaceType,
8276 fminfo->panScan.numWindows,
8277 fminfo->nConcealedMacroblocks,
8278 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308279 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008280 fminfo->aspectRatio.aspectRatioX,
8281 fminfo->aspectRatio.aspectRatioY);
8282
8283 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8284 DEBUG_PRINT_HIGH(
8285 "------------------------------\n"
8286 " Pan Scan Frame Num: %lu \n"
8287 " Rectangle x: %ld \n"
8288 " Rectangle y: %ld \n"
8289 " Rectangle dx: %ld \n"
8290 " Rectangle dy: %ld \n",
8291 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8292 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8293 }
8294
8295 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8296 } else if (extra->eType == OMX_ExtraDataNone) {
8297 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8298 } else {
8299 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008300 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008301}
8302
8303void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008304 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008305{
Arun Menon906de572013-06-18 17:01:40 -07008306 OMX_STREAMINTERLACEFORMAT *interlace_format;
8307 OMX_U32 mbaff = 0;
8308 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8309 return;
8310 }
8311 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8312 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8313 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8314 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8315 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8316 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8317 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8318 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8319 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8320 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8321 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8322 interlace_format->bInterlaceFormat = OMX_FALSE;
8323 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8324 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8325 } else {
8326 interlace_format->bInterlaceFormat = OMX_TRUE;
8327 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8328 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8329 }
8330 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008331}
8332
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008333void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008334 struct vdec_aspectratioinfo *aspect_ratio_info,
8335 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008336{
Arun Menon906de572013-06-18 17:01:40 -07008337 m_extradata = frame_info;
8338 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8339 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308340 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008341 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008342}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008343
8344void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008345 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308346 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008347 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008348{
Arun Menon906de572013-06-18 17:01:40 -07008349 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8350 struct msm_vidc_panscan_window *panscan_window;
8351 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008352 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008353 }
Arun Menon906de572013-06-18 17:01:40 -07008354 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8355 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8356 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8357 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8358 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8359 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8360 switch (picture_type) {
8361 case PICTURE_TYPE_I:
8362 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8363 break;
8364 case PICTURE_TYPE_P:
8365 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8366 break;
8367 case PICTURE_TYPE_B:
8368 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8369 break;
8370 default:
8371 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8372 }
8373 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8374 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8375 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8376 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8377 else
8378 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8379 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8380 frame_info->nConcealedMacroblocks = num_conceal_mb;
8381 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308382 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008383 frame_info->panScan.numWindows = 0;
8384 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8385 if (m_disp_hor_size && m_disp_vert_size) {
8386 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8387 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8388 }
8389 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008390
Arun Menon906de572013-06-18 17:01:40 -07008391 if (panscan_payload) {
8392 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8393 panscan_window = &panscan_payload->wnd[0];
8394 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8395 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8396 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8397 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8398 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8399 panscan_window++;
8400 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008401 }
Arun Menon906de572013-06-18 17:01:40 -07008402 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8403 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008404}
8405
8406void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8407{
Arun Menon906de572013-06-18 17:01:40 -07008408 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8409 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8410 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8411 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8412 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8413 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8414 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8415 *portDefn = m_port_def;
8416 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8417 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
8418 portDefn->format.video.nFrameWidth,
8419 portDefn->format.video.nStride,
8420 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008421}
8422
8423void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8424{
Arun Menon906de572013-06-18 17:01:40 -07008425 if (!client_extradata) {
8426 return;
8427 }
8428 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8429 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8430 extra->eType = OMX_ExtraDataNone;
8431 extra->nDataSize = 0;
8432 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008433
Arun Menon906de572013-06-18 17:01:40 -07008434 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008435}
8436
8437OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8438{
Arun Menon906de572013-06-18 17:01:40 -07008439 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8440 if (index >= drv_ctx.ip_buf.actualcount) {
8441 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8442 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008443 }
Arun Menon906de572013-06-18 17:01:40 -07008444 if (m_desc_buffer_ptr == NULL) {
8445 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8446 calloc( (sizeof(desc_buffer_hdr)),
8447 drv_ctx.ip_buf.actualcount);
8448 if (m_desc_buffer_ptr == NULL) {
8449 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8450 return OMX_ErrorInsufficientResources;
8451 }
8452 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008453
Arun Menon906de572013-06-18 17:01:40 -07008454 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8455 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
8456 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8457 return OMX_ErrorInsufficientResources;
8458 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008459
Arun Menon906de572013-06-18 17:01:40 -07008460 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008461}
8462
8463void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8464{
Arun Menon906de572013-06-18 17:01:40 -07008465 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8466 if (m_demux_entries < 8192) {
8467 m_demux_offsets[m_demux_entries++] = address_offset;
8468 }
8469 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008470}
8471
8472void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8473{
Arun Menon906de572013-06-18 17:01:40 -07008474 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8475 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8476 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008477
Arun Menon906de572013-06-18 17:01:40 -07008478 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008479
Arun Menon906de572013-06-18 17:01:40 -07008480 while (index < bytes_to_parse) {
8481 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8482 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8483 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8484 (buf[index+2] == 0x01)) ) {
8485 //Found start code, insert address offset
8486 insert_demux_addr_offset(index);
8487 if (buf[index+2] == 0x01) // 3 byte start code
8488 index += 3;
8489 else //4 byte start code
8490 index += 4;
8491 } else
8492 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008493 }
Arun Menon906de572013-06-18 17:01:40 -07008494 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8495 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008496}
8497
8498OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8499{
Arun Menon906de572013-06-18 17:01:40 -07008500 //fix this, handle 3 byte start code, vc1 terminator entry
8501 OMX_U8 *p_demux_data = NULL;
8502 OMX_U32 desc_data = 0;
8503 OMX_U32 start_addr = 0;
8504 OMX_U32 nal_size = 0;
8505 OMX_U32 suffix_byte = 0;
8506 OMX_U32 demux_index = 0;
8507 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008508
Arun Menon906de572013-06-18 17:01:40 -07008509 if (m_desc_buffer_ptr == NULL) {
8510 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8511 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008512 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008513
Arun Menon906de572013-06-18 17:01:40 -07008514 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8515 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8516 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8517 return OMX_ErrorBadParameter;
8518 }
8519
8520 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8521
8522 if ( ((OMX_U8*)p_demux_data == NULL) ||
8523 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8524 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8525 return OMX_ErrorBadParameter;
8526 } else {
8527 for (; demux_index < m_demux_entries; demux_index++) {
8528 desc_data = 0;
8529 start_addr = m_demux_offsets[demux_index];
8530 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8531 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8532 } else {
8533 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8534 }
8535 if (demux_index < (m_demux_entries - 1)) {
8536 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8537 } else {
8538 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8539 }
8540 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8541 (void *)start_addr,
8542 suffix_byte,
8543 nal_size,
8544 demux_index);
8545 desc_data = (start_addr >> 3) << 1;
8546 desc_data |= (start_addr & 7) << 21;
8547 desc_data |= suffix_byte << 24;
8548
8549 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8550 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8551 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8552 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8553
8554 p_demux_data += 16;
8555 }
8556 if (codec_type_parse == CODEC_TYPE_VC1) {
8557 DEBUG_PRINT_LOW("VC1 terminator entry");
8558 desc_data = 0;
8559 desc_data = 0x82 << 24;
8560 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8561 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8562 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8563 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8564 p_demux_data += 16;
8565 m_demux_entries++;
8566 }
8567 //Add zero word to indicate end of descriptors
8568 memset(p_demux_data, 0, sizeof(OMX_U32));
8569
8570 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8571 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8572 }
8573 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8574 m_demux_entries = 0;
8575 DEBUG_PRINT_LOW("Demux table complete!");
8576 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008577}
8578
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008579OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008580{
Arun Menon906de572013-06-18 17:01:40 -07008581 OMX_ERRORTYPE err = OMX_ErrorNone;
8582 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8583 if (iDivXDrmDecrypt) {
8584 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8585 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008586 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008587 delete iDivXDrmDecrypt;
8588 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008589 }
8590 } else {
8591 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
8592 err = OMX_ErrorUndefined;
8593 }
8594 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008595}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008596
Vinay Kaliada4f4422013-01-09 10:45:03 -08008597omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8598{
Arun Menon906de572013-06-18 17:01:40 -07008599 enabled = false;
8600 omx = NULL;
8601 init_members();
8602 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008603}
8604
8605void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8606{
Arun Menon906de572013-06-18 17:01:40 -07008607 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008608}
8609
Arun Menon906de572013-06-18 17:01:40 -07008610void omx_vdec::allocate_color_convert_buf::init_members()
8611{
8612 allocated_count = 0;
8613 buffer_size_req = 0;
8614 buffer_alignment_req = 0;
8615 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8616 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8617 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8618 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008619#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008620 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008621#endif
Arun Menon906de572013-06-18 17:01:40 -07008622 for (int i = 0; i < MAX_COUNT; i++)
8623 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008624}
8625
Arun Menon906de572013-06-18 17:01:40 -07008626omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8627{
8628 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008629}
8630
8631bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8632{
Arun Menon906de572013-06-18 17:01:40 -07008633 bool status = true;
8634 unsigned int src_size = 0, destination_size = 0;
8635 OMX_COLOR_FORMATTYPE drv_color_format;
8636 if (!omx) {
8637 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8638 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008639 }
Arun Menon906de572013-06-18 17:01:40 -07008640 if (!enabled) {
8641 DEBUG_PRINT_HIGH("\n No color conversion required");
8642 return status;
8643 }
8644 pthread_mutex_lock(&omx->c_lock);
8645 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8646 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8647 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
8648 status = false;
8649 goto fail_update_buf_req;
8650 }
8651 c2d.close();
8652 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8653 omx->drv_ctx.video_resolution.frame_width,
8654 NV12_128m,YCbCr420P);
8655 if (status) {
8656 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8657 if (status)
8658 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8659 }
8660 if (status) {
8661 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8662 !destination_size) {
8663 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
8664 "driver size %d destination size %d",
8665 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8666 status = false;
8667 c2d.close();
8668 buffer_size_req = 0;
8669 } else {
8670 buffer_size_req = destination_size;
8671 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8672 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8673 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8674 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8675 }
8676 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008677fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008678 pthread_mutex_unlock(&omx->c_lock);
8679 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008680}
8681
8682bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008683 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008684{
Arun Menon906de572013-06-18 17:01:40 -07008685 bool status = true;
8686 OMX_COLOR_FORMATTYPE drv_color_format;
8687 if (!omx) {
8688 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8689 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008690 }
Arun Menon906de572013-06-18 17:01:40 -07008691 pthread_mutex_lock(&omx->c_lock);
8692 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8693 drv_color_format = (OMX_COLOR_FORMATTYPE)
8694 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8695 else {
8696 DEBUG_PRINT_ERROR("\n Incorrect color format");
8697 status = false;
8698 }
8699 if (status && (drv_color_format != dest_color_format)) {
8700 DEBUG_PRINT_LOW("Enabling C2D\n");
8701 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
8702 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
8703 status = false;
8704 } else {
8705 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8706 if (enabled)
8707 c2d.destroy();
8708 enabled = false;
8709 if (!c2d.init()) {
8710 DEBUG_PRINT_ERROR("\n open failed for c2d");
8711 status = false;
8712 } else
8713 enabled = true;
8714 }
8715 } else {
8716 if (enabled)
8717 c2d.destroy();
8718 enabled = false;
8719 }
8720 pthread_mutex_unlock(&omx->c_lock);
8721 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008722}
8723
8724OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8725{
Arun Menon906de572013-06-18 17:01:40 -07008726 if (!omx) {
8727 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8728 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008729 }
Arun Menon906de572013-06-18 17:01:40 -07008730 if (!enabled)
8731 return omx->m_out_mem_ptr;
8732 return m_out_mem_ptr_client;
8733}
8734
8735 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
8736(OMX_BUFFERHEADERTYPE *bufadd)
8737{
8738 if (!omx) {
8739 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8740 return NULL;
8741 }
8742 if (!enabled)
8743 return bufadd;
8744
8745 unsigned index = 0;
8746 index = bufadd - omx->m_out_mem_ptr;
8747 if (index < omx->drv_ctx.op_buf.actualcount) {
8748 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
8749 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
8750 bool status;
8751 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
8752 pthread_mutex_lock(&omx->c_lock);
8753 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
8754 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
8755 pmem_baseaddress[index], pmem_baseaddress[index]);
8756 pthread_mutex_unlock(&omx->c_lock);
8757 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
8758 if (!status) {
8759 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
8760 m_out_mem_ptr_client[index].nFilledLen = 0;
8761 return &m_out_mem_ptr_client[index];
8762 }
8763 } else
8764 m_out_mem_ptr_client[index].nFilledLen = 0;
8765 return &m_out_mem_ptr_client[index];
8766 }
8767 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
8768 return NULL;
8769}
8770
8771 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
8772(OMX_BUFFERHEADERTYPE *bufadd)
8773{
8774 if (!omx) {
8775 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8776 return NULL;
8777 }
8778 if (!enabled)
8779 return bufadd;
8780 unsigned index = 0;
8781 index = bufadd - m_out_mem_ptr_client;
8782 if (index < omx->drv_ctx.op_buf.actualcount) {
8783 return &omx->m_out_mem_ptr[index];
8784 }
8785 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
8786 return NULL;
8787}
8788 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
8789(unsigned int &buffer_size)
8790{
8791 bool status = true;
8792 pthread_mutex_lock(&omx->c_lock);
8793 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008794 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07008795 else {
8796 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
8797 DEBUG_PRINT_ERROR("\n Get buffer size failed");
8798 status = false;
8799 goto fail_get_buffer_size;
8800 }
8801 }
8802 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
8803 buffer_size = omx->drv_ctx.op_buf.buffer_size;
8804 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8805 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008806fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07008807 pthread_mutex_unlock(&omx->c_lock);
8808 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008809}
8810OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07008811 OMX_BUFFERHEADERTYPE *bufhdr)
8812{
8813 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008814
Arun Menon906de572013-06-18 17:01:40 -07008815 if (!enabled)
8816 return omx->free_output_buffer(bufhdr);
8817 if (enabled && omx->is_component_secure())
8818 return OMX_ErrorNone;
8819 if (!allocated_count || !bufhdr) {
8820 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
8821 return OMX_ErrorBadParameter;
8822 }
8823 index = bufhdr - m_out_mem_ptr_client;
8824 if (index >= omx->drv_ctx.op_buf.actualcount) {
8825 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
8826 return OMX_ErrorBadParameter;
8827 }
8828 if (pmem_fd[index] > 0) {
8829 munmap(pmem_baseaddress[index], buffer_size_req);
8830 close(pmem_fd[index]);
8831 }
8832 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008833#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008834 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008835#endif
Arun Menon906de572013-06-18 17:01:40 -07008836 m_heap_ptr[index].video_heap_ptr = NULL;
8837 if (allocated_count > 0)
8838 allocated_count--;
8839 else
8840 allocated_count = 0;
8841 if (!allocated_count) {
8842 pthread_mutex_lock(&omx->c_lock);
8843 c2d.close();
8844 init_members();
8845 pthread_mutex_unlock(&omx->c_lock);
8846 }
8847 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008848}
8849
8850OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07008851 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008852{
Arun Menon906de572013-06-18 17:01:40 -07008853 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8854 if (!enabled) {
8855 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
8856 return eRet;
8857 }
8858 if (enabled && omx->is_component_secure()) {
8859 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
8860 omx->is_component_secure());
8861 return OMX_ErrorUnsupportedSetting;
8862 }
8863 if (!bufferHdr || bytes > buffer_size_req) {
8864 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
8865 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
8866 buffer_size_req,bytes);
8867 return OMX_ErrorBadParameter;
8868 }
8869 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
8870 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
8871 return OMX_ErrorInsufficientResources;
8872 }
8873 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
8874 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
8875 port,appData,omx->drv_ctx.op_buf.buffer_size);
8876 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
8877 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
8878 return eRet;
8879 }
8880 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
8881 omx->drv_ctx.op_buf.actualcount) {
8882 DEBUG_PRINT_ERROR("\n Invalid header index %d",
8883 (temp_bufferHdr - omx->m_out_mem_ptr));
8884 return OMX_ErrorUndefined;
8885 }
8886 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008887#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008888 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
8889 buffer_size_req,buffer_alignment_req,
8890 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
8891 0);
8892 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
8893 if (op_buf_ion_info[i].ion_device_fd < 0) {
8894 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
8895 return OMX_ErrorInsufficientResources;
8896 }
8897 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
8898 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008899
Arun Menon906de572013-06-18 17:01:40 -07008900 if (pmem_baseaddress[i] == MAP_FAILED) {
8901 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
8902 close(pmem_fd[i]);
8903 omx->free_ion_memory(&op_buf_ion_info[i]);
8904 return OMX_ErrorInsufficientResources;
8905 }
8906 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
8907 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
8908 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008909#endif
Arun Menon906de572013-06-18 17:01:40 -07008910 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
8911 m_pmem_info_client[i].offset = 0;
8912 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
8913 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8914 m_platform_list_client[i].nEntries = 1;
8915 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
8916 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
8917 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
8918 m_out_mem_ptr_client[i].nFilledLen = 0;
8919 m_out_mem_ptr_client[i].nFlags = 0;
8920 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8921 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
8922 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
8923 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
8924 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
8925 m_out_mem_ptr_client[i].pAppPrivate = appData;
8926 *bufferHdr = &m_out_mem_ptr_client[i];
8927 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
8928 allocated_count++;
8929 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008930}
8931
8932bool omx_vdec::is_component_secure()
8933{
Arun Menon906de572013-06-18 17:01:40 -07008934 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008935}
8936
8937bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
8938{
Arun Menon906de572013-06-18 17:01:40 -07008939 bool status = true;
8940 if (!enabled) {
8941 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8942 dest_color_format = (OMX_COLOR_FORMATTYPE)
8943 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8944 else
8945 status = false;
8946 } else {
8947 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8948 status = false;
8949 } else
8950 dest_color_format = OMX_COLOR_FormatYUV420Planar;
8951 }
8952 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008953}
Arun Menonbdb80b02013-08-12 17:45:54 -07008954
8955#ifdef META_DATA_MODE_SUPPORTED
8956void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
8957{
8958 int i = 0;
8959 bool buf_present = false;
8960 pthread_mutex_lock(&m_lock);
8961 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
8962 //check the buffer fd, offset, uv addr with list contents
8963 //If present increment reference.
8964 if ((out_dynamic_list[i].fd == fd) &&
8965 (out_dynamic_list[i].offset == offset)) {
8966 out_dynamic_list[i].ref_count++;
8967 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d\n",
8968 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
8969 buf_present = true;
8970 break;
8971 }
8972 }
8973 if (!buf_present) {
8974 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
8975 //search for a entry to insert details of the new buffer
8976 if (out_dynamic_list[i].dup_fd == 0) {
8977 out_dynamic_list[i].fd = fd;
8978 out_dynamic_list[i].offset = offset;
8979 out_dynamic_list[i].dup_fd = dup(fd);
8980 out_dynamic_list[i].ref_count++;
8981 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d\n",
8982 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
8983 break;
8984 }
8985 }
8986 }
8987 pthread_mutex_unlock(&m_lock);
8988}
8989
8990void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
8991{
8992 int i = 0;
8993 pthread_mutex_lock(&m_lock);
8994 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
8995 //check the buffer fd, offset, uv addr with list contents
8996 //If present decrement reference.
8997 if ((out_dynamic_list[i].fd == fd) &&
8998 (out_dynamic_list[i].offset == offset)) {
8999 out_dynamic_list[i].ref_count--;
9000 if (out_dynamic_list[i].ref_count == 0) {
9001 close(out_dynamic_list[i].dup_fd);
9002 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d\n",
9003 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
9004 out_dynamic_list[i].dup_fd = 0;
9005 out_dynamic_list[i].fd = 0;
9006 out_dynamic_list[i].offset = 0;
9007 }
9008 break;
9009 }
9010 }
9011 if (i >= drv_ctx.op_buf.actualcount) {
9012 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list\n");
9013 }
9014 pthread_mutex_unlock(&m_lock);
9015}
9016#endif