blob: 1d07edb11f248890772d0daf7007c709613a65bb [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;
2904 if (!client_buffers.get_buffer_req(buffer_size)) {
2905 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
2906 eRet = OMX_ErrorBadParameter;
2907 } else {
2908 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
2909 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) {
2910 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
2911 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
2912 drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
2913 drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
2914 drv_ctx.extradata_info.buffer_size;
2915 eRet = set_buffer_req(&drv_ctx.op_buf);
2916 if (eRet == OMX_ErrorNone)
2917 m_port_def = *portDefn;
2918 } else {
2919 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
2920 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
2921 portDefn->nBufferCountActual, portDefn->nBufferSize);
2922 eRet = OMX_ErrorBadParameter;
2923 }
2924 }
2925 } else if (OMX_DirInput == portDefn->eDir) {
2926 bool port_format_changed = false;
2927 if ((portDefn->format.video.xFramerate >> 16) > 0 &&
2928 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
2929 // Frame rate only should be set if this is a "known value" or to
2930 // activate ts prediction logic (arbitrary mode only) sending input
2931 // timestamps with max value (LLONG_MAX).
2932 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
2933 portDefn->format.video.xFramerate >> 16);
2934 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
2935 drv_ctx.frame_rate.fps_denominator);
2936 if (!drv_ctx.frame_rate.fps_numerator) {
2937 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
2938 drv_ctx.frame_rate.fps_numerator = 30;
2939 }
2940 if (drv_ctx.frame_rate.fps_denominator)
2941 drv_ctx.frame_rate.fps_numerator = (int)
2942 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
2943 drv_ctx.frame_rate.fps_denominator = 1;
2944 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
2945 drv_ctx.frame_rate.fps_numerator;
2946 DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
2947 frm_int, drv_ctx.frame_rate.fps_numerator /
2948 (float)drv_ctx.frame_rate.fps_denominator);
2949 }
2950 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
2951 if (drv_ctx.video_resolution.frame_height !=
2952 portDefn->format.video.nFrameHeight ||
2953 drv_ctx.video_resolution.frame_width !=
2954 portDefn->format.video.nFrameWidth) {
2955 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
2956 portDefn->format.video.nFrameWidth,
2957 portDefn->format.video.nFrameHeight);
2958 port_format_changed = true;
2959 if (portDefn->format.video.nFrameHeight != 0x0 &&
2960 portDefn->format.video.nFrameWidth != 0x0) {
2961 update_resolution(portDefn->format.video.nFrameWidth,
2962 portDefn->format.video.nFrameHeight,
2963 portDefn->format.video.nFrameWidth,
2964 portDefn->format.video.nFrameHeight);
2965 eRet = is_video_session_supported();
2966 if (eRet)
2967 break;
2968 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2969 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
2970 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
2971 fmt.fmt.pix_mp.pixelformat = output_capability;
2972 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);
2973 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
2974 if (ret) {
2975 DEBUG_PRINT_ERROR("\n Set Resolution failed");
2976 eRet = OMX_ErrorUnsupportedSetting;
2977 } else
2978 eRet = get_buffer_req(&drv_ctx.op_buf);
2979 }
2980 }
2981 if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
2982 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
2983 port_format_changed = true;
2984 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
2985 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
2986 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
2987 (~(buffer_prop->alignment - 1));
2988 eRet = set_buffer_req(buffer_prop);
2989 }
2990 if (false == port_format_changed) {
2991 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
2992 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
2993 portDefn->nBufferCountActual, portDefn->nBufferSize);
2994 eRet = OMX_ErrorBadParameter;
2995 }
2996 } else if (portDefn->eDir == OMX_DirMax) {
2997 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
2998 (int)portDefn->nPortIndex);
2999 eRet = OMX_ErrorBadPortIndex;
3000 }
3001 }
3002 break;
3003 case OMX_IndexParamVideoPortFormat: {
3004 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3005 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3006 int ret=0;
3007 struct v4l2_format fmt;
3008 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3009 portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003010
Arun Menon906de572013-06-18 17:01:40 -07003011 if (1 == portFmt->nPortIndex) {
3012 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3013 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3014 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3015 fmt.fmt.pix_mp.pixelformat = capture_capability;
3016 enum vdec_output_fromat op_format;
3017 if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3018 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
3019 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
3020 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
3021 else if (portFmt->eColorFormat ==
3022 (OMX_COLOR_FORMATTYPE)
3023 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3024 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3025 else
3026 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003027
Arun Menon906de572013-06-18 17:01:40 -07003028 if (eRet == OMX_ErrorNone) {
3029 drv_ctx.output_format = op_format;
3030 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3031 if (ret) {
3032 DEBUG_PRINT_ERROR("\n Set output format failed");
3033 eRet = OMX_ErrorUnsupportedSetting;
3034 /*TODO: How to handle this case */
3035 } else {
3036 eRet = get_buffer_req(&drv_ctx.op_buf);
3037 }
3038 }
3039 if (eRet == OMX_ErrorNone) {
3040 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3041 DEBUG_PRINT_ERROR("\n Set color format failed");
3042 eRet = OMX_ErrorBadParameter;
3043 }
3044 }
3045 }
3046 }
3047 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003048
Arun Menon906de572013-06-18 17:01:40 -07003049 case OMX_QcomIndexPortDefn: {
3050 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3051 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
3052 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
3053 portFmt->nFramePackingFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003054
Arun Menon906de572013-06-18 17:01:40 -07003055 /* Input port */
3056 if (portFmt->nPortIndex == 0) {
3057 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3058 if (secure_mode) {
3059 arbitrary_bytes = false;
3060 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3061 eRet = OMX_ErrorUnsupportedSetting;
3062 } else {
3063 arbitrary_bytes = true;
3064 }
3065 } else if (portFmt->nFramePackingFormat ==
3066 OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3067 arbitrary_bytes = false;
3068 } else {
3069 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
3070 portFmt->nFramePackingFormat);
3071 eRet = OMX_ErrorUnsupportedSetting;
3072 }
3073 } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3074 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3075 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3076 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3077 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3078 m_out_mem_region_smi = OMX_TRUE;
3079 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3080 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3081 m_use_output_pmem = OMX_TRUE;
3082 }
3083 }
3084 }
3085 }
3086 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003087
Arun Menon906de572013-06-18 17:01:40 -07003088 case OMX_IndexParamStandardComponentRole: {
3089 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3090 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3091 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3092 comp_role->cRole);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003093
Arun Menon906de572013-06-18 17:01:40 -07003094 if ((m_state == OMX_StateLoaded)&&
3095 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3096 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3097 } else {
3098 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3099 return OMX_ErrorIncorrectStateOperation;
3100 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003101
Arun Menon906de572013-06-18 17:01:40 -07003102 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3103 if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3104 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3105 } else {
3106 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3107 eRet =OMX_ErrorUnsupportedSetting;
3108 }
3109 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3110 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3111 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3112 } else {
3113 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3114 eRet = OMX_ErrorUnsupportedSetting;
3115 }
3116 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3117 if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3118 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3119 } else {
3120 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3121 eRet =OMX_ErrorUnsupportedSetting;
3122 }
3123 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3124 if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3125 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3126 } else {
3127 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3128 eRet = OMX_ErrorUnsupportedSetting;
3129 }
3130 } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3131 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3132 ) {
3133 if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3134 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3135 } else {
3136 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3137 eRet =OMX_ErrorUnsupportedSetting;
3138 }
3139 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3140 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3141 ) {
3142 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3143 strlcpy((char*)m_cRole,"video_decoder.vc1",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.vp8",OMX_MAX_STRINGNAME_SIZE)) {
3149 if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3150 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
3151 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3152 } else {
3153 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3154 eRet = OMX_ErrorUnsupportedSetting;
3155 }
3156 } else {
3157 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3158 eRet = OMX_ErrorInvalidComponentName;
3159 }
3160 break;
3161 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003162
Arun Menon906de572013-06-18 17:01:40 -07003163 case OMX_IndexParamPriorityMgmt: {
3164 if (m_state != OMX_StateLoaded) {
3165 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3166 return OMX_ErrorIncorrectStateOperation;
3167 }
3168 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
3169 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
3170 priorityMgmtype->nGroupID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003171
Arun Menon906de572013-06-18 17:01:40 -07003172 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
3173 priorityMgmtype->nGroupPriority);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003174
Arun Menon906de572013-06-18 17:01:40 -07003175 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3176 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003177
Arun Menon906de572013-06-18 17:01:40 -07003178 break;
3179 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003180
Arun Menon906de572013-06-18 17:01:40 -07003181 case OMX_IndexParamCompBufferSupplier: {
3182 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3183 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3184 bufferSupplierType->eBufferSupplier);
3185 if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3186 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003187
Arun Menon906de572013-06-18 17:01:40 -07003188 else
Shalaj Jain273b3e02012-06-22 19:08:03 -07003189
Arun Menon906de572013-06-18 17:01:40 -07003190 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003191
Arun Menon906de572013-06-18 17:01:40 -07003192 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003193
Arun Menon906de572013-06-18 17:01:40 -07003194 }
3195 case OMX_IndexParamVideoAvc: {
3196 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3197 paramIndex);
3198 break;
3199 }
3200 case OMX_IndexParamVideoH263: {
3201 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3202 paramIndex);
3203 break;
3204 }
3205 case OMX_IndexParamVideoMpeg4: {
3206 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3207 paramIndex);
3208 break;
3209 }
3210 case OMX_IndexParamVideoMpeg2: {
3211 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3212 paramIndex);
3213 break;
3214 }
3215 case OMX_QcomIndexParamVideoDecoderPictureOrder: {
3216 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3217 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3218 struct v4l2_control control;
3219 int pic_order,rc=0;
3220 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3221 pictureOrder->eOutputPictureOrder);
3222 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3223 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3224 } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3225 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3226 time_stamp_dts.set_timestamp_reorder_mode(false);
3227 } else
3228 eRet = OMX_ErrorBadParameter;
3229 if (eRet == OMX_ErrorNone) {
3230 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3231 control.value = pic_order;
3232 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3233 if (rc) {
3234 DEBUG_PRINT_ERROR("\n Set picture order failed");
3235 eRet = OMX_ErrorUnsupportedSetting;
3236 }
3237 }
3238 break;
3239 }
3240 case OMX_QcomIndexParamConcealMBMapExtraData:
3241 if (!secure_mode)
3242 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
3243 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3244 else {
3245 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3246 eRet = OMX_ErrorUnsupportedSetting;
3247 }
3248 break;
3249 case OMX_QcomIndexParamFrameInfoExtraData: {
3250 if (!secure_mode)
3251 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
3252 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3253 else {
3254 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3255 eRet = OMX_ErrorUnsupportedSetting;
3256 }
3257 break;
3258 }
3259 case OMX_QcomIndexParamInterlaceExtraData:
3260 if (!secure_mode)
3261 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
3262 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3263 else {
3264 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3265 eRet = OMX_ErrorUnsupportedSetting;
3266 }
3267 break;
3268 case OMX_QcomIndexParamH264TimeInfo:
3269 if (!secure_mode)
3270 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
3271 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3272 else {
3273 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3274 eRet = OMX_ErrorUnsupportedSetting;
3275 }
3276 break;
3277 case OMX_QcomIndexParamVideoDivx: {
3278 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3279 }
3280 break;
3281 case OMX_QcomIndexPlatformPvt: {
3282 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3283 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3284 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3285 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3286 eRet = OMX_ErrorUnsupportedSetting;
3287 } else {
3288 m_out_pvt_entry_pmem = OMX_TRUE;
3289 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3290 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3291 m_use_output_pmem = OMX_TRUE;
3292 }
3293 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003294
Arun Menon906de572013-06-18 17:01:40 -07003295 }
3296 break;
3297 case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
3298 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3299 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3300 struct v4l2_control control;
3301 int rc;
3302 drv_ctx.idr_only_decoding = 1;
3303 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3304 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3305 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3306 if (rc) {
3307 DEBUG_PRINT_ERROR("\n Set picture order failed");
3308 eRet = OMX_ErrorUnsupportedSetting;
3309 } else {
3310 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3311 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3312 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3313 if (rc) {
3314 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3315 eRet = OMX_ErrorUnsupportedSetting;
3316 }
3317 /*Setting sync frame decoding on driver might change buffer
3318 * requirements so update them here*/
3319 if (get_buffer_req(&drv_ctx.ip_buf)) {
3320 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer i/p requirements");
3321 eRet = OMX_ErrorUnsupportedSetting;
3322 }
3323 if (get_buffer_req(&drv_ctx.op_buf)) {
3324 DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer o/p requirements");
3325 eRet = OMX_ErrorUnsupportedSetting;
3326 }
3327 }
3328 }
3329 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003330
Arun Menon906de572013-06-18 17:01:40 -07003331 case OMX_QcomIndexParamIndexExtraDataType: {
3332 if (!secure_mode) {
3333 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3334 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3335 (extradataIndexType->bEnabled == OMX_TRUE) &&
3336 (extradataIndexType->nPortIndex == 1)) {
3337 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
3338 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003339
Arun Menon906de572013-06-18 17:01:40 -07003340 }
3341 }
3342 }
3343 break;
3344 case OMX_QcomIndexParamEnableSmoothStreaming: {
Arun Menonc821d8a2013-06-15 10:03:29 -07003345#ifndef SMOOTH_STREAMING_DISABLED
Arun Menon906de572013-06-18 17:01:40 -07003346 struct v4l2_control control;
3347 struct v4l2_format fmt;
3348 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3349 control.value = 1;
3350 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3351 if (rc < 0) {
3352 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3353 eRet = OMX_ErrorHardware;
3354 }
Arun Menonbc0922f2013-06-24 13:02:15 -07003355#else
Arun Menon906de572013-06-18 17:01:40 -07003356 eRet = OMX_ErrorUnsupportedSetting;
Arun Menonc821d8a2013-06-15 10:03:29 -07003357#endif
Arun Menon906de572013-06-18 17:01:40 -07003358 }
3359 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003360#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003361 /* Need to allow following two set_parameters even in Idle
3362 * state. This is ANDROID architecture which is not in sync
3363 * with openmax standard. */
3364 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
3365 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3366 if (enableNativeBuffers) {
3367 m_enable_android_native_buffers = enableNativeBuffers->enable;
3368 }
3369 }
3370 break;
3371 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
3372 eRet = use_android_native_buffer(hComp, paramData);
3373 }
3374 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003375#endif
Arun Menon906de572013-06-18 17:01:40 -07003376 case OMX_QcomIndexParamEnableTimeStampReorder: {
3377 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3378 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
3379 if (reorder->bEnable == OMX_TRUE) {
3380 frm_int =0;
3381 time_stamp_dts.set_timestamp_reorder_mode(true);
3382 } else
3383 time_stamp_dts.set_timestamp_reorder_mode(false);
3384 } else {
3385 time_stamp_dts.set_timestamp_reorder_mode(false);
3386 if (reorder->bEnable == OMX_TRUE) {
3387 eRet = OMX_ErrorUnsupportedSetting;
3388 }
3389 }
3390 }
3391 break;
3392 case OMX_IndexParamVideoProfileLevelCurrent: {
3393 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
3394 (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
3395 if (pParam) {
3396 m_profile_lvl.eProfile = pParam->eProfile;
3397 m_profile_lvl.eLevel = pParam->eLevel;
3398 }
3399 break;
Arun Menon888aa852013-05-30 11:24:42 -07003400
Arun Menon906de572013-06-18 17:01:40 -07003401 }
Arun Menonbdb80b02013-08-12 17:45:54 -07003402#ifdef META_DATA_MODE_SUPPORTED
Arun Menone5652482013-08-04 13:33:05 -07003403 case OMX_QcomIndexParamVideoMetaBufferMode:
3404 {
3405 StoreMetaDataInBuffersParams *metabuffer =
3406 (StoreMetaDataInBuffersParams *)paramData;
3407 if (!metabuffer) {
3408 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
3409 eRet = OMX_ErrorBadParameter;
3410 break;
3411 }
3412 if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3413 //set property dynamic buffer mode to driver.
3414 struct v4l2_control control;
3415 struct v4l2_format fmt;
3416 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
3417 if (metabuffer->bStoreMetaData == true) {
3418 control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
3419 } else {
3420 control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
3421 }
3422 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3423 if (!rc) {
3424 DEBUG_PRINT_HIGH(" %s buffer mode\n",
3425 (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
Arun Menonbdb80b02013-08-12 17:45:54 -07003426 dynamic_buf_mode = metabuffer->bStoreMetaData;
Arun Menone5652482013-08-04 13:33:05 -07003427 } else {
3428 DEBUG_PRINT_ERROR("Failed to %s buffer mode\n",
3429 (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
3430 eRet = OMX_ErrorUnsupportedSetting;
3431 }
3432 } else {
3433 DEBUG_PRINT_ERROR(
3434 "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %d\n",
3435 metabuffer->nPortIndex);
3436 eRet = OMX_ErrorUnsupportedSetting;
3437 }
3438 break;
3439 }
Arun Menonbdb80b02013-08-12 17:45:54 -07003440#endif
Arun Menon906de572013-06-18 17:01:40 -07003441 default: {
3442 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3443 eRet = OMX_ErrorUnsupportedIndex;
3444 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003445 }
Arun Menon906de572013-06-18 17:01:40 -07003446 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003447}
3448
3449/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003450 FUNCTION
3451 omx_vdec::GetConfig
Shalaj Jain273b3e02012-06-22 19:08:03 -07003452
Arun Menon906de572013-06-18 17:01:40 -07003453 DESCRIPTION
3454 OMX Get Config Method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003455
Arun Menon906de572013-06-18 17:01:40 -07003456 PARAMETERS
3457 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003458
Arun Menon906de572013-06-18 17:01:40 -07003459 RETURN VALUE
3460 OMX Error None if successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003461
Arun Menon906de572013-06-18 17:01:40 -07003462 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003463OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003464 OMX_IN OMX_INDEXTYPE configIndex,
3465 OMX_INOUT OMX_PTR configData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003466{
Arun Menon906de572013-06-18 17:01:40 -07003467 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003468
Arun Menon906de572013-06-18 17:01:40 -07003469 if (m_state == OMX_StateInvalid) {
3470 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003471 return OMX_ErrorInvalidState;
3472 }
Arun Menon906de572013-06-18 17:01:40 -07003473
3474 switch ((unsigned long)configIndex) {
3475 case OMX_QcomIndexConfigInterlaced: {
3476 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3477 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3478 if (configFmt->nPortIndex == 1) {
3479 if (configFmt->nIndex == 0) {
3480 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3481 } else if (configFmt->nIndex == 1) {
3482 configFmt->eInterlaceType =
3483 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3484 } else if (configFmt->nIndex == 2) {
3485 configFmt->eInterlaceType =
3486 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3487 } else {
3488 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3489 " NoMore Interlaced formats\n");
3490 eRet = OMX_ErrorNoMore;
3491 }
3492
3493 } else {
3494 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3495 (int)configFmt->nPortIndex);
3496 eRet = OMX_ErrorBadPortIndex;
3497 }
3498 break;
3499 }
3500 case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
3501 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3502 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3503 decoderinstances->nNumOfInstances = 16;
3504 /*TODO: How to handle this case */
3505 break;
3506 }
3507 case OMX_QcomIndexConfigVideoFramePackingArrangement: {
3508 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3509 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3510 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3511 h264_parser->get_frame_pack_data(configFmt);
3512 } else {
3513 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3514 }
3515 break;
3516 }
3517 case OMX_IndexConfigCommonOutputCrop: {
3518 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3519 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3520 break;
3521 }
3522 default: {
3523 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3524 eRet = OMX_ErrorBadParameter;
3525 }
3526
Shalaj Jain273b3e02012-06-22 19:08:03 -07003527 }
Arun Menon906de572013-06-18 17:01:40 -07003528
3529 return eRet;
3530}
3531
3532/* ======================================================================
3533 FUNCTION
3534 omx_vdec::SetConfig
3535
3536 DESCRIPTION
3537 OMX Set Config method implementation
3538
3539 PARAMETERS
3540 <TBD>.
3541
3542 RETURN VALUE
3543 OMX Error None if successful.
3544 ========================================================================== */
3545OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3546 OMX_IN OMX_INDEXTYPE configIndex,
3547 OMX_IN OMX_PTR configData)
3548{
3549 if (m_state == OMX_StateInvalid) {
3550 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3551 return OMX_ErrorInvalidState;
3552 }
3553
3554 OMX_ERRORTYPE ret = OMX_ErrorNone;
3555 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3556
3557 DEBUG_PRINT_LOW("\n Set Config Called");
3558
3559 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
3560 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3561 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3562 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
3563 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3564 OMX_U32 extra_size;
3565 // Parsing done here for the AVC atom is definitely not generic
3566 // Currently this piece of code is working, but certainly
3567 // not tested with all .mp4 files.
3568 // Incase of failure, we might need to revisit this
3569 // for a generic piece of code.
3570
3571 // Retrieve size of NAL length field
3572 // byte #4 contains the size of NAL lenght field
3573 nal_length = (config->pData[4] & 0x03) + 1;
3574
3575 extra_size = 0;
3576 if (nal_length > 2) {
3577 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3578 extra_size = (nal_length - 2) * 2;
3579 }
3580
3581 // SPS starts from byte #6
3582 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3583 OMX_U8 *pDestBuf;
3584 m_vendor_config.nPortIndex = config->nPortIndex;
3585
3586 // minus 6 --> SPS starts from byte #6
3587 // minus 1 --> picture param set byte to be ignored from avcatom
3588 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3589 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3590 OMX_U32 len;
3591 OMX_U8 index = 0;
3592 // case where SPS+PPS is sent as part of set_config
3593 pDestBuf = m_vendor_config.pData;
3594
3595 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
3596 m_vendor_config.nPortIndex,
3597 m_vendor_config.nDataSize,
3598 m_vendor_config.pData);
3599 while (index < 2) {
3600 uint8 *psize;
3601 len = *pSrcBuf;
3602 len = len << 8;
3603 len |= *(pSrcBuf + 1);
3604 psize = (uint8 *) & len;
3605 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3606 for (unsigned int i = 0; i < nal_length; i++) {
3607 pDestBuf[i] = psize[nal_length - 1 - i];
3608 }
3609 //memcpy(pDestBuf,pSrcBuf,(len+2));
3610 pDestBuf += len + nal_length;
3611 pSrcBuf += len + 2;
3612 index++;
3613 pSrcBuf++; // skip picture param set
3614 len = 0;
3615 }
3616 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3617 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3618 m_vendor_config.nPortIndex = config->nPortIndex;
3619 m_vendor_config.nDataSize = config->nDataSize;
3620 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3621 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3622 } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3623 if (m_vendor_config.pData) {
3624 free(m_vendor_config.pData);
3625 m_vendor_config.pData = NULL;
3626 m_vendor_config.nDataSize = 0;
3627 }
3628
3629 if (((*((OMX_U32 *) config->pData)) &
3630 VC1_SP_MP_START_CODE_MASK) ==
3631 VC1_SP_MP_START_CODE) {
3632 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3633 m_vendor_config.nPortIndex = config->nPortIndex;
3634 m_vendor_config.nDataSize = config->nDataSize;
3635 m_vendor_config.pData =
3636 (OMX_U8 *) malloc(config->nDataSize);
3637 memcpy(m_vendor_config.pData, config->pData,
3638 config->nDataSize);
3639 m_vc1_profile = VC1_SP_MP_RCV;
3640 } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
3641 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3642 m_vendor_config.nPortIndex = config->nPortIndex;
3643 m_vendor_config.nDataSize = config->nDataSize;
3644 m_vendor_config.pData =
3645 (OMX_U8 *) malloc((config->nDataSize));
3646 memcpy(m_vendor_config.pData, config->pData,
3647 config->nDataSize);
3648 m_vc1_profile = VC1_AP;
3649 } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
3650 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3651 m_vendor_config.nPortIndex = config->nPortIndex;
3652 m_vendor_config.nDataSize = config->nDataSize;
3653 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3654 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3655 m_vc1_profile = VC1_SP_MP_RCV;
3656 } else {
3657 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3658 }
3659 }
3660 return ret;
3661 } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3662 struct v4l2_control temp;
3663 temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
3664
3665 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3666 switch (pNal->nNaluBytes) {
3667 case 0:
3668 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
3669 break;
3670 case 2:
3671 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
3672 break;
3673 case 4:
3674 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
3675 break;
3676 default:
3677 return OMX_ErrorUnsupportedSetting;
3678 }
3679
3680 if (!arbitrary_bytes) {
3681 /* In arbitrary bytes mode, the assembler strips out nal size and replaces
3682 * with start code, so only need to notify driver in frame by frame mode */
3683 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
3684 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
3685 return OMX_ErrorHardware;
3686 }
3687 }
3688
3689 nal_length = pNal->nNaluBytes;
3690 m_frame_parser.init_nal_length(nal_length);
3691
3692 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
3693 return ret;
3694 } else if (configIndex == OMX_IndexVendorVideoFrameRate) {
3695 OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
3696 DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps);
3697
3698 if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
3699 if (config->bEnabled) {
3700 if ((config->nFps >> 16) > 0) {
3701 DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d",
3702 config->nFps >> 16);
3703 Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
3704 drv_ctx.frame_rate.fps_denominator);
3705
3706 if (!drv_ctx.frame_rate.fps_numerator) {
3707 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3708 drv_ctx.frame_rate.fps_numerator = 30;
3709 }
3710
3711 if (drv_ctx.frame_rate.fps_denominator) {
3712 drv_ctx.frame_rate.fps_numerator = (int)
3713 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3714 }
3715
3716 drv_ctx.frame_rate.fps_denominator = 1;
3717 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3718 drv_ctx.frame_rate.fps_numerator;
3719
3720 struct v4l2_outputparm oparm;
3721 /*XXX: we're providing timing info as seconds per frame rather than frames
3722 * per second.*/
3723 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
3724 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
3725
3726 struct v4l2_streamparm sparm;
3727 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3728 sparm.parm.output = oparm;
3729 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
3730 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
3731 performance might be affected");
3732 ret = OMX_ErrorHardware;
3733 }
3734 client_set_fps = true;
3735 } else {
3736 DEBUG_PRINT_ERROR("Frame rate not supported.");
3737 ret = OMX_ErrorUnsupportedSetting;
3738 }
3739 } else {
3740 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
3741 client_set_fps = false;
3742 }
3743 } else {
3744 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
3745 (int)config->nPortIndex);
3746 ret = OMX_ErrorBadPortIndex;
3747 }
3748
3749 return ret;
3750 }
3751
3752 return OMX_ErrorNotImplemented;
3753}
3754
3755/* ======================================================================
3756 FUNCTION
3757 omx_vdec::GetExtensionIndex
3758
3759 DESCRIPTION
3760 OMX GetExtensionIndex method implementaion. <TBD>
3761
3762 PARAMETERS
3763 <TBD>.
3764
3765 RETURN VALUE
3766 OMX Error None if everything successful.
3767
3768 ========================================================================== */
3769OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3770 OMX_IN OMX_STRING paramName,
3771 OMX_OUT OMX_INDEXTYPE* indexType)
3772{
3773 if (m_state == OMX_StateInvalid) {
3774 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3775 return OMX_ErrorInvalidState;
3776 } else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3777 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3778 } else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003779 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3780 }
3781#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003782 else if (!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003783 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
Arun Menon906de572013-06-18 17:01:40 -07003784 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003785 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
Arun Menon906de572013-06-18 17:01:40 -07003786 } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003787 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3788 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
Arun Menon906de572013-06-18 17:01:40 -07003789 } else if (!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003790 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3791 }
3792#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07003793#ifdef META_DATA_MODE_SUPPORTED
Arun Menone5652482013-08-04 13:33:05 -07003794 else if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers", sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) {
3795 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
3796 }
Arun Menonbdb80b02013-08-12 17:45:54 -07003797#endif
Arun Menon906de572013-06-18 17:01:40 -07003798 else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003799 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3800 return OMX_ErrorNotImplemented;
3801 }
3802 return OMX_ErrorNone;
3803}
3804
3805/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003806 FUNCTION
3807 omx_vdec::GetState
Shalaj Jain273b3e02012-06-22 19:08:03 -07003808
Arun Menon906de572013-06-18 17:01:40 -07003809 DESCRIPTION
3810 Returns the state information back to the caller.<TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003811
Arun Menon906de572013-06-18 17:01:40 -07003812 PARAMETERS
3813 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003814
Arun Menon906de572013-06-18 17:01:40 -07003815 RETURN VALUE
3816 Error None if everything is successful.
3817 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003818OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003819 OMX_OUT OMX_STATETYPE* state)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003820{
Arun Menon906de572013-06-18 17:01:40 -07003821 *state = m_state;
3822 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
3823 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003824}
3825
3826/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003827 FUNCTION
3828 omx_vdec::ComponentTunnelRequest
Shalaj Jain273b3e02012-06-22 19:08:03 -07003829
Arun Menon906de572013-06-18 17:01:40 -07003830 DESCRIPTION
3831 OMX Component Tunnel Request method implementation. <TBD>
Shalaj Jain273b3e02012-06-22 19:08:03 -07003832
Arun Menon906de572013-06-18 17:01:40 -07003833 PARAMETERS
3834 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003835
Arun Menon906de572013-06-18 17:01:40 -07003836 RETURN VALUE
3837 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003838
Arun Menon906de572013-06-18 17:01:40 -07003839 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07003840OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07003841 OMX_IN OMX_U32 port,
3842 OMX_IN OMX_HANDLETYPE peerComponent,
3843 OMX_IN OMX_U32 peerPort,
3844 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003845{
Arun Menon906de572013-06-18 17:01:40 -07003846 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3847 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003848}
3849
3850/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07003851 FUNCTION
3852 omx_vdec::UseOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07003853
Arun Menon906de572013-06-18 17:01:40 -07003854 DESCRIPTION
3855 Helper function for Use buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07003856
Arun Menon906de572013-06-18 17:01:40 -07003857 PARAMETERS
3858 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07003859
Arun Menon906de572013-06-18 17:01:40 -07003860 RETURN VALUE
3861 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07003862
Arun Menon906de572013-06-18 17:01:40 -07003863 ========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003864OMX_ERRORTYPE omx_vdec::allocate_extradata()
3865{
3866#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003867 if (drv_ctx.extradata_info.buffer_size) {
3868 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
3869 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3870 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3871 free_ion_memory(&drv_ctx.extradata_info.ion);
3872 }
3873 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
3874 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
3875 drv_ctx.extradata_info.size, 4096,
3876 &drv_ctx.extradata_info.ion.ion_alloc_data,
3877 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
3878 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
3879 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
3880 return OMX_ErrorInsufficientResources;
3881 }
3882 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
3883 drv_ctx.extradata_info.size,
3884 PROT_READ|PROT_WRITE, MAP_SHARED,
3885 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
3886 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
3887 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
3888 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3889 free_ion_memory(&drv_ctx.extradata_info.ion);
3890 return OMX_ErrorInsufficientResources;
3891 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003892 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003893#endif
Arun Menon906de572013-06-18 17:01:40 -07003894 return OMX_ErrorNone;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003895}
3896
Arun Menon906de572013-06-18 17:01:40 -07003897void omx_vdec::free_extradata()
3898{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003899#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07003900 if (drv_ctx.extradata_info.uaddr) {
3901 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
3902 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
3903 free_ion_memory(&drv_ctx.extradata_info.ion);
3904 }
3905 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07003906#endif
3907}
3908
Shalaj Jain273b3e02012-06-22 19:08:03 -07003909OMX_ERRORTYPE omx_vdec::use_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07003910 OMX_IN OMX_HANDLETYPE hComp,
3911 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3912 OMX_IN OMX_U32 port,
3913 OMX_IN OMX_PTR appData,
3914 OMX_IN OMX_U32 bytes,
3915 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003916{
Arun Menon906de572013-06-18 17:01:40 -07003917 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3918 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
3919 unsigned i= 0; // Temporary counter
3920 struct vdec_setbuffer_cmd setbuffers;
3921 OMX_PTR privateAppData = NULL;
3922 private_handle_t *handle = NULL;
3923 OMX_U8 *buff = buffer;
3924 struct v4l2_buffer buf;
3925 struct v4l2_plane plane[VIDEO_MAX_PLANES];
3926 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003927
Arun Menon906de572013-06-18 17:01:40 -07003928 if (!m_out_mem_ptr) {
3929 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
3930 eRet = allocate_output_headers();
3931 if (eRet == OMX_ErrorNone)
3932 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07003933 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003934
Arun Menon906de572013-06-18 17:01:40 -07003935 if (eRet == OMX_ErrorNone) {
3936 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
3937 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
3938 break;
3939 }
3940 }
3941 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003942
Arun Menon906de572013-06-18 17:01:40 -07003943 if (i >= drv_ctx.op_buf.actualcount) {
3944 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
3945 eRet = OMX_ErrorInsufficientResources;
3946 }
3947
Arun Menonbdb80b02013-08-12 17:45:54 -07003948#ifdef META_DATA_MODE_SUPPORTED
3949 if (dynamic_buf_mode) {
3950 *bufferHdr = (m_out_mem_ptr + i );
3951 (*bufferHdr)->pBuffer = NULL;
3952 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
3953 enum v4l2_buf_type buf_type;
3954 int rr = 0;
3955 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3956 if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
3957 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
3958 return OMX_ErrorInsufficientResources;
3959 } else {
3960 streaming[CAPTURE_PORT] = true;
3961 DEBUG_PRINT_LOW("STREAMON Successful");
3962 }
3963 }
3964 BITMASK_SET(&m_out_bm_count,i);
3965 (*bufferHdr)->pAppPrivate = appData;
3966 (*bufferHdr)->pBuffer = buffer;
3967 (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
3968 return eRet;
3969 }
3970#endif
Arun Menon906de572013-06-18 17:01:40 -07003971 if (eRet == OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003972#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07003973 if (m_enable_android_native_buffers) {
3974 if (m_use_android_native_buffers) {
3975 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
3976 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3977 handle = (private_handle_t *)nBuf->handle;
3978 privateAppData = params->pAppPrivate;
3979 } else {
3980 handle = (private_handle_t *)buff;
3981 privateAppData = appData;
3982 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003983
Arun Menon906de572013-06-18 17:01:40 -07003984 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
3985 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
3986 " expected %u, got %lu",
3987 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
3988 return OMX_ErrorBadParameter;
3989 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003990
Arun Menon906de572013-06-18 17:01:40 -07003991 if (!m_use_android_native_buffers) {
3992 if (!secure_mode) {
3993 buff = (OMX_U8*)mmap(0, handle->size,
3994 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3995 if (buff == MAP_FAILED) {
3996 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3997 return OMX_ErrorInsufficientResources;
3998 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003999 }
4000 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004001#if defined(_ANDROID_ICS_)
Arun Menon906de572013-06-18 17:01:40 -07004002 native_buffer[i].nativehandle = handle;
4003 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004004#endif
Arun Menon906de572013-06-18 17:01:40 -07004005 if (!handle) {
4006 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4007 return OMX_ErrorBadParameter;
4008 }
4009 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4010 drv_ctx.ptr_outputbuffer[i].offset = 0;
4011 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4012 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4013 drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
4014 } else
4015#endif
4016
4017 if (!ouput_egl_buffers && !m_use_output_pmem) {
4018#ifdef USE_ION
4019 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4020 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4021 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4022 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4023 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
4024 DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd);
4025 return OMX_ErrorInsufficientResources;
4026 }
4027 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4028 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4029#else
4030 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4031 open (MEM_DEVICE,O_RDWR);
4032
4033 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
4034 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
4035 return OMX_ErrorInsufficientResources;
4036 }
4037
4038 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
4039 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
4040 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4041 open (MEM_DEVICE,O_RDWR);
4042 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
4043 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
4044 return OMX_ErrorInsufficientResources;
4045 }
4046 }
4047
4048 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4049 drv_ctx.op_buf.buffer_size,
4050 drv_ctx.op_buf.alignment)) {
4051 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4052 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4053 return OMX_ErrorInsufficientResources;
4054 }
4055#endif
4056 if (!secure_mode) {
4057 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4058 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4059 PROT_READ|PROT_WRITE, MAP_SHARED,
4060 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4061 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4062 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4063#ifdef USE_ION
4064 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4065#endif
4066 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
4067 return OMX_ErrorInsufficientResources;
4068 }
4069 }
4070 drv_ctx.ptr_outputbuffer[i].offset = 0;
4071 privateAppData = appData;
4072 } else {
4073
4074 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4075 if (!appData || !bytes ) {
4076 if (!secure_mode && !buffer) {
4077 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4078 return OMX_ErrorBadParameter;
4079 }
4080 }
4081
4082 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4083 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4084 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4085 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4086 !pmem_list->nEntries ||
4087 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4088 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4089 return OMX_ErrorBadParameter;
4090 }
4091 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4092 pmem_list->entryList->entry;
4093 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
4094 pmem_info->pmem_fd);
4095 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4096 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4097 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4098 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4099 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4100 privateAppData = appData;
4101 }
4102 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4103 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4104
4105 *bufferHdr = (m_out_mem_ptr + i );
4106 if (secure_mode)
4107 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4108 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4109 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4110 sizeof (vdec_bufferpayload));
4111
4112 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4113 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4114 drv_ctx.ptr_outputbuffer[i].pmem_fd );
4115
4116 buf.index = i;
4117 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4118 buf.memory = V4L2_MEMORY_USERPTR;
4119 plane[0].length = drv_ctx.op_buf.buffer_size;
4120 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4121 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
4122 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4123 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4124 plane[0].data_offset = 0;
4125 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4126 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4127 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4128 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4129#ifdef USE_ION
4130 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4131#endif
4132 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4133 plane[extra_idx].data_offset = 0;
4134 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4135 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004136 return OMX_ErrorBadParameter;
4137 }
Arun Menon906de572013-06-18 17:01:40 -07004138 buf.m.planes = plane;
4139 buf.length = drv_ctx.num_planes;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004140
Arun Menon906de572013-06-18 17:01:40 -07004141 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4142 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4143 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004144 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004145 }
4146
Arun Menon906de572013-06-18 17:01:40 -07004147 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4148 enum v4l2_buf_type buf_type;
4149 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4150 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4151 return OMX_ErrorInsufficientResources;
4152 } else {
4153 streaming[CAPTURE_PORT] = true;
4154 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004155 }
4156 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004157
Arun Menon906de572013-06-18 17:01:40 -07004158 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4159 if (m_enable_android_native_buffers) {
4160 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4161 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4162 } else {
4163 (*bufferHdr)->pBuffer = buff;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004164 }
Arun Menon906de572013-06-18 17:01:40 -07004165 (*bufferHdr)->pAppPrivate = privateAppData;
4166 BITMASK_SET(&m_out_bm_count,i);
4167 }
4168 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004169}
4170
4171/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004172 FUNCTION
4173 omx_vdec::use_input_heap_buffers
Shalaj Jain273b3e02012-06-22 19:08:03 -07004174
Arun Menon906de572013-06-18 17:01:40 -07004175 DESCRIPTION
4176 OMX Use Buffer Heap allocation method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004177
Arun Menon906de572013-06-18 17:01:40 -07004178 PARAMETERS
4179 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004180
Arun Menon906de572013-06-18 17:01:40 -07004181 RETURN VALUE
4182 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004183
Arun Menon906de572013-06-18 17:01:40 -07004184 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004185OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
Arun Menon906de572013-06-18 17:01:40 -07004186 OMX_IN OMX_HANDLETYPE hComp,
4187 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4188 OMX_IN OMX_U32 port,
4189 OMX_IN OMX_PTR appData,
4190 OMX_IN OMX_U32 bytes,
4191 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004192{
Arun Menon906de572013-06-18 17:01:40 -07004193 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4194 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4195 if (!m_inp_heap_ptr)
4196 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4197 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4198 drv_ctx.ip_buf.actualcount);
4199 if (!m_phdr_pmem_ptr)
4200 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4201 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4202 drv_ctx.ip_buf.actualcount);
4203 if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4204 DEBUG_PRINT_ERROR("Insufficent memory");
4205 eRet = OMX_ErrorInsufficientResources;
4206 } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4207 input_use_buffer = true;
4208 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4209 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4210 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4211 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4212 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4213 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4214 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4215 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4216 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
4217 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4218 (unsigned)NULL, (unsigned)NULL)) {
4219 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4220 return OMX_ErrorInsufficientResources;
4221 }
4222 m_in_alloc_cnt++;
4223 } else {
4224 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4225 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004226 }
Arun Menon906de572013-06-18 17:01:40 -07004227 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004228}
4229
4230/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004231 FUNCTION
4232 omx_vdec::UseBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004233
Arun Menon906de572013-06-18 17:01:40 -07004234 DESCRIPTION
4235 OMX Use Buffer method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004236
Arun Menon906de572013-06-18 17:01:40 -07004237 PARAMETERS
4238 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004239
Arun Menon906de572013-06-18 17:01:40 -07004240 RETURN VALUE
4241 OMX Error None , if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004242
Arun Menon906de572013-06-18 17:01:40 -07004243 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004244OMX_ERRORTYPE omx_vdec::use_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004245 OMX_IN OMX_HANDLETYPE hComp,
4246 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4247 OMX_IN OMX_U32 port,
4248 OMX_IN OMX_PTR appData,
4249 OMX_IN OMX_U32 bytes,
4250 OMX_IN OMX_U8* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004251{
Arun Menon906de572013-06-18 17:01:40 -07004252 OMX_ERRORTYPE error = OMX_ErrorNone;
4253 struct vdec_setbuffer_cmd setbuffers;
4254
4255 if (bufferHdr == NULL || bytes == 0) {
4256 if (!secure_mode && buffer == NULL) {
4257 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4258 return OMX_ErrorBadParameter;
4259 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004260 }
Arun Menon906de572013-06-18 17:01:40 -07004261 if (m_state == OMX_StateInvalid) {
4262 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4263 return OMX_ErrorInvalidState;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004264 }
Arun Menon906de572013-06-18 17:01:40 -07004265 if (port == OMX_CORE_INPUT_PORT_INDEX)
4266 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4267 else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4268 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4269 else {
4270 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4271 error = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004272 }
Arun Menon906de572013-06-18 17:01:40 -07004273 DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
4274 if (error == OMX_ErrorNone) {
4275 if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4276 // Send the callback now
4277 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4278 post_event(OMX_CommandStateSet,OMX_StateIdle,
4279 OMX_COMPONENT_GENERATE_EVENT);
4280 }
4281 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4282 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4283 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4284 post_event(OMX_CommandPortEnable,
4285 OMX_CORE_INPUT_PORT_INDEX,
4286 OMX_COMPONENT_GENERATE_EVENT);
4287 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4288 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4289 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4290 post_event(OMX_CommandPortEnable,
4291 OMX_CORE_OUTPUT_PORT_INDEX,
4292 OMX_COMPONENT_GENERATE_EVENT);
4293 }
4294 }
4295 return error;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004296}
4297
4298OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
Arun Menon906de572013-06-18 17:01:40 -07004299 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004300{
Arun Menon906de572013-06-18 17:01:40 -07004301 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4302 if (m_inp_heap_ptr[bufferindex].pBuffer)
4303 free(m_inp_heap_ptr[bufferindex].pBuffer);
4304 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4305 }
4306 if (pmem_bufferHdr)
4307 free_input_buffer(pmem_bufferHdr);
4308 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004309}
4310
4311OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4312{
Arun Menon906de572013-06-18 17:01:40 -07004313 unsigned int index = 0;
4314 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4315 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004316 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004317
Arun Menon906de572013-06-18 17:01:40 -07004318 index = bufferHdr - m_inp_mem_ptr;
4319 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4320
4321 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
4322 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4323 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4324 struct vdec_setbuffer_cmd setbuffers;
4325 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4326 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4327 sizeof (vdec_bufferpayload));
4328 if (!secure_mode) {
4329 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4330 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4331 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p",
4332 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4333 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4334 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4335 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4336 }
4337 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4338 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4339 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4340 free(m_desc_buffer_ptr[index].buf_addr);
4341 m_desc_buffer_ptr[index].buf_addr = NULL;
4342 m_desc_buffer_ptr[index].desc_data_size = 0;
4343 }
4344#ifdef USE_ION
4345 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4346#endif
4347 }
4348 }
4349
4350 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004351}
4352
4353OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4354{
Arun Menon906de572013-06-18 17:01:40 -07004355 unsigned int index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004356
Arun Menon906de572013-06-18 17:01:40 -07004357 if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4358 return OMX_ErrorBadParameter;
4359 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004360
Arun Menon906de572013-06-18 17:01:40 -07004361 index = bufferHdr - m_out_mem_ptr;
4362 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004363
Arun Menon906de572013-06-18 17:01:40 -07004364 if (index < drv_ctx.op_buf.actualcount
4365 && drv_ctx.ptr_outputbuffer) {
4366 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
4367 drv_ctx.ptr_outputbuffer[index].bufferaddr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004368
Arun Menon906de572013-06-18 17:01:40 -07004369 struct vdec_setbuffer_cmd setbuffers;
4370 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4371 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4372 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004373#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004374 if (m_enable_android_native_buffers) {
Praveen Chavan212671f2013-04-05 20:00:42 -07004375 if (!secure_mode) {
Arun Menon906de572013-06-18 17:01:40 -07004376 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4377 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4378 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4379 }
Praveen Chavan212671f2013-04-05 20:00:42 -07004380 }
Arun Menon906de572013-06-18 17:01:40 -07004381 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4382 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004383#endif
Arun Menon906de572013-06-18 17:01:40 -07004384 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4385 if (!secure_mode) {
4386 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4387 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4388 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p",
4389 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
4390 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4391 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
4392 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
4393 }
4394 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4395 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004396#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004397 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004398#endif
Arun Menon906de572013-06-18 17:01:40 -07004399 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004400#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07004401 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004402#endif
Arun Menon906de572013-06-18 17:01:40 -07004403 if (release_output_done()) {
4404 free_extradata();
4405 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004406 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004407
Arun Menon906de572013-06-18 17:01:40 -07004408 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004409
4410}
4411
4412OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07004413 OMX_BUFFERHEADERTYPE **bufferHdr,
4414 OMX_U32 port,
4415 OMX_PTR appData,
4416 OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004417{
Arun Menon906de572013-06-18 17:01:40 -07004418 OMX_BUFFERHEADERTYPE *input = NULL;
4419 unsigned char *buf_addr = NULL;
4420 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4421 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004422
Arun Menon906de572013-06-18 17:01:40 -07004423 /* Sanity Check*/
4424 if (bufferHdr == NULL) {
4425 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004426 }
4427
Arun Menon906de572013-06-18 17:01:40 -07004428 if (m_inp_heap_ptr == NULL) {
4429 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4430 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4431 drv_ctx.ip_buf.actualcount);
4432 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4433 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4434 drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004435
Arun Menon906de572013-06-18 17:01:40 -07004436 if (m_inp_heap_ptr == NULL) {
4437 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4438 return OMX_ErrorInsufficientResources;
4439 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004440 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004441
Arun Menon906de572013-06-18 17:01:40 -07004442 /*Find a Free index*/
4443 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4444 if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
4445 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4446 break;
4447 }
4448 }
4449
4450 if (i < drv_ctx.ip_buf.actualcount) {
4451 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4452
4453 if (buf_addr == NULL) {
4454 return OMX_ErrorInsufficientResources;
4455 }
4456
4457 *bufferHdr = (m_inp_heap_ptr + i);
4458 input = *bufferHdr;
4459 BITMASK_SET(&m_heap_inp_bm_count,i);
4460
4461 input->pBuffer = (OMX_U8 *)buf_addr;
4462 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4463 input->nVersion.nVersion = OMX_SPEC_VERSION;
4464 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4465 input->pAppPrivate = appData;
4466 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4467 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4468 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4469 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
4470 /*Add the Buffers to freeq*/
4471 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4472 (unsigned)NULL, (unsigned)NULL)) {
4473 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4474 return OMX_ErrorInsufficientResources;
4475 }
4476 } else {
4477 return OMX_ErrorBadParameter;
4478 }
4479
4480 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004481
4482}
4483
4484
4485/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004486 FUNCTION
4487 omx_vdec::AllocateInputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004488
Arun Menon906de572013-06-18 17:01:40 -07004489 DESCRIPTION
4490 Helper function for allocate buffer in the input pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004491
Arun Menon906de572013-06-18 17:01:40 -07004492 PARAMETERS
4493 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004494
Arun Menon906de572013-06-18 17:01:40 -07004495 RETURN VALUE
4496 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07004497
Arun Menon906de572013-06-18 17:01:40 -07004498 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004499OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004500 OMX_IN OMX_HANDLETYPE hComp,
4501 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4502 OMX_IN OMX_U32 port,
4503 OMX_IN OMX_PTR appData,
4504 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004505{
4506
Arun Menon906de572013-06-18 17:01:40 -07004507 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4508 struct vdec_setbuffer_cmd setbuffers;
4509 OMX_BUFFERHEADERTYPE *input = NULL;
4510 unsigned i = 0;
4511 unsigned char *buf_addr = NULL;
4512 int pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004513
Arun Menon906de572013-06-18 17:01:40 -07004514 if (bytes != drv_ctx.ip_buf.buffer_size) {
4515 DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
4516 bytes, drv_ctx.ip_buf.buffer_size);
4517 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004518 }
4519
Arun Menon906de572013-06-18 17:01:40 -07004520 if (!m_inp_mem_ptr) {
4521 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4522 drv_ctx.ip_buf.actualcount,
4523 drv_ctx.ip_buf.buffer_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004524
Arun Menon906de572013-06-18 17:01:40 -07004525 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4526 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4527
4528 if (m_inp_mem_ptr == NULL) {
4529 return OMX_ErrorInsufficientResources;
4530 }
4531
4532 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4533 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4534
4535 if (drv_ctx.ptr_inputbuffer == NULL) {
4536 return OMX_ErrorInsufficientResources;
4537 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004538#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004539 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4540 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004541
Arun Menon906de572013-06-18 17:01:40 -07004542 if (drv_ctx.ip_buf_ion_info == NULL) {
4543 return OMX_ErrorInsufficientResources;
4544 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004545#endif
4546
Arun Menon906de572013-06-18 17:01:40 -07004547 for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4548 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004549#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004550 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004551#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07004552 }
4553 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004554
Arun Menon906de572013-06-18 17:01:40 -07004555 for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4556 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4557 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4558 break;
4559 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004560 }
Arun Menon906de572013-06-18 17:01:40 -07004561
4562 if (i < drv_ctx.ip_buf.actualcount) {
4563 struct v4l2_buffer buf;
4564 struct v4l2_plane plane;
4565 int rc;
4566 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4567#ifdef USE_ION
4568 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4569 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4570 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4571 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
4572 if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4573 return OMX_ErrorInsufficientResources;
4574 }
4575 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4576#else
4577 pmem_fd = open (MEM_DEVICE,O_RDWR);
4578
4579 if (pmem_fd < 0) {
4580 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4581 return OMX_ErrorInsufficientResources;
4582 }
4583
4584 if (pmem_fd == 0) {
4585 pmem_fd = open (MEM_DEVICE,O_RDWR);
4586
4587 if (pmem_fd < 0) {
4588 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4589 return OMX_ErrorInsufficientResources;
4590 }
4591 }
4592
4593 if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4594 drv_ctx.ip_buf.alignment)) {
4595 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4596 close(pmem_fd);
4597 return OMX_ErrorInsufficientResources;
4598 }
4599#endif
4600 if (!secure_mode) {
4601 buf_addr = (unsigned char *)mmap(NULL,
4602 drv_ctx.ip_buf.buffer_size,
4603 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4604
4605 if (buf_addr == MAP_FAILED) {
4606 close(pmem_fd);
4607#ifdef USE_ION
4608 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4609#endif
4610 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4611 return OMX_ErrorInsufficientResources;
4612 }
4613 }
4614 *bufferHdr = (m_inp_mem_ptr + i);
4615 if (secure_mode)
4616 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4617 else
4618 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4619 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4620 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4621 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4622 drv_ctx.ptr_inputbuffer [i].offset = 0;
4623
4624
4625 buf.index = i;
4626 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4627 buf.memory = V4L2_MEMORY_USERPTR;
4628 plane.bytesused = 0;
4629 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4630 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4631 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4632 plane.reserved[1] = 0;
4633 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4634 buf.m.planes = &plane;
4635 buf.length = 1;
4636
4637 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
4638 drv_ctx.ptr_inputbuffer[i].bufferaddr);
4639
4640 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4641
4642 if (rc) {
4643 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4644 /*TODO: How to handle this case */
4645 return OMX_ErrorInsufficientResources;
4646 }
4647
4648 input = *bufferHdr;
4649 BITMASK_SET(&m_inp_bm_count,i);
4650 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4651 if (secure_mode)
4652 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4653 else
4654 input->pBuffer = (OMX_U8 *)buf_addr;
4655 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4656 input->nVersion.nVersion = OMX_SPEC_VERSION;
4657 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4658 input->pAppPrivate = appData;
4659 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4660 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4661
4662 if (drv_ctx.disable_dmx) {
4663 eRet = allocate_desc_buffer(i);
4664 }
4665 } else {
4666 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4667 eRet = OMX_ErrorInsufficientResources;
4668 }
4669 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004670}
4671
4672
4673/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004674 FUNCTION
4675 omx_vdec::AllocateOutputBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004676
Arun Menon906de572013-06-18 17:01:40 -07004677 DESCRIPTION
4678 Helper fn for AllocateBuffer in the output pin
Shalaj Jain273b3e02012-06-22 19:08:03 -07004679
Arun Menon906de572013-06-18 17:01:40 -07004680 PARAMETERS
4681 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004682
Arun Menon906de572013-06-18 17:01:40 -07004683 RETURN VALUE
4684 OMX Error None if everything went well.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004685
Arun Menon906de572013-06-18 17:01:40 -07004686 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004687OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07004688 OMX_IN OMX_HANDLETYPE hComp,
4689 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4690 OMX_IN OMX_U32 port,
4691 OMX_IN OMX_PTR appData,
4692 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07004693{
Arun Menon906de572013-06-18 17:01:40 -07004694 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4695 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4696 unsigned i= 0; // Temporary counter
4697 struct vdec_setbuffer_cmd setbuffers;
4698 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004699#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004700 int ion_device_fd =-1;
4701 struct ion_allocation_data ion_alloc_data;
4702 struct ion_fd_data fd_ion_data;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004703#endif
Arun Menon906de572013-06-18 17:01:40 -07004704 if (!m_out_mem_ptr) {
4705 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4706 drv_ctx.op_buf.actualcount,
4707 drv_ctx.op_buf.buffer_size);
4708 int nBufHdrSize = 0;
4709 int nPlatformEntrySize = 0;
4710 int nPlatformListSize = 0;
4711 int nPMEMInfoSize = 0;
4712 int pmem_fd = -1;
4713 unsigned char *pmem_baseaddress = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004714
Arun Menon906de572013-06-18 17:01:40 -07004715 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4716 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4717 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004718
Arun Menon906de572013-06-18 17:01:40 -07004719 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4720 drv_ctx.op_buf.actualcount);
4721 nBufHdrSize = drv_ctx.op_buf.actualcount *
4722 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004723
Arun Menon906de572013-06-18 17:01:40 -07004724 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4725 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4726 nPlatformListSize = drv_ctx.op_buf.actualcount *
4727 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4728 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4729 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004730
Arun Menon906de572013-06-18 17:01:40 -07004731 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4732 sizeof(OMX_BUFFERHEADERTYPE),
4733 nPMEMInfoSize,
4734 nPlatformListSize);
4735 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4736 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004737#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004738 ion_device_fd = alloc_map_ion_memory(
4739 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4740 drv_ctx.op_buf.alignment,
4741 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
4742 if (ion_device_fd < 0) {
4743 return OMX_ErrorInsufficientResources;
4744 }
4745 pmem_fd = fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004746#else
Arun Menon906de572013-06-18 17:01:40 -07004747 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004748
Arun Menon906de572013-06-18 17:01:40 -07004749 if (pmem_fd < 0) {
4750 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4751 drv_ctx.op_buf.buffer_size);
4752 return OMX_ErrorInsufficientResources;
4753 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004754
Arun Menon906de572013-06-18 17:01:40 -07004755 if (pmem_fd == 0) {
4756 pmem_fd = open (MEM_DEVICE,O_RDWR);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004757
Arun Menon906de572013-06-18 17:01:40 -07004758 if (pmem_fd < 0) {
4759 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4760 drv_ctx.op_buf.buffer_size);
4761 return OMX_ErrorInsufficientResources;
4762 }
4763 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004764
Arun Menon906de572013-06-18 17:01:40 -07004765 if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4766 drv_ctx.op_buf.actualcount,
4767 drv_ctx.op_buf.alignment)) {
4768 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4769 close(pmem_fd);
4770 return OMX_ErrorInsufficientResources;
4771 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004772#endif
Arun Menon906de572013-06-18 17:01:40 -07004773 if (!secure_mode) {
4774 pmem_baseaddress = (unsigned char *)mmap(NULL,
4775 (drv_ctx.op_buf.buffer_size *
4776 drv_ctx.op_buf.actualcount),
4777 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4778 if (pmem_baseaddress == MAP_FAILED) {
4779 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4780 drv_ctx.op_buf.buffer_size);
4781 close(pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004782#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004783 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004784#endif
Arun Menon906de572013-06-18 17:01:40 -07004785 return OMX_ErrorInsufficientResources;
4786 }
4787 }
4788 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
4789 // Alloc mem for platform specific info
4790 char *pPtr=NULL;
4791 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4792 nPMEMInfoSize,1);
4793 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4794 calloc (sizeof(struct vdec_bufferpayload),
4795 drv_ctx.op_buf.actualcount);
4796 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
4797 calloc (sizeof (struct vdec_output_frameinfo),
4798 drv_ctx.op_buf.actualcount);
4799#ifdef USE_ION
4800 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4801 calloc (sizeof(struct vdec_ion),
4802 drv_ctx.op_buf.actualcount);
4803#endif
4804
4805 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4806 && drv_ctx.ptr_respbuffer) {
4807 drv_ctx.ptr_outputbuffer[0].mmaped_size =
4808 (drv_ctx.op_buf.buffer_size *
4809 drv_ctx.op_buf.actualcount);
4810 bufHdr = m_out_mem_ptr;
4811 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4812 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4813 (((char *) m_platform_list) + nPlatformListSize);
4814 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4815 (((char *) m_platform_entry) + nPlatformEntrySize);
4816 pPlatformList = m_platform_list;
4817 pPlatformEntry = m_platform_entry;
4818 pPMEMInfo = m_pmem_info;
4819
4820 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
4821
4822 // Settting the entire storage nicely
4823 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
4824 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
4825 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4826 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4827 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
4828 // Set the values when we determine the right HxW param
4829 bufHdr->nAllocLen = bytes;
4830 bufHdr->nFilledLen = 0;
4831 bufHdr->pAppPrivate = appData;
4832 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
4833 // Platform specific PMEM Information
4834 // Initialize the Platform Entry
4835 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
4836 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4837 pPlatformEntry->entry = pPMEMInfo;
4838 // Initialize the Platform List
4839 pPlatformList->nEntries = 1;
4840 pPlatformList->entryList = pPlatformEntry;
4841 // Keep pBuffer NULL till vdec is opened
4842 bufHdr->pBuffer = NULL;
4843 bufHdr->nOffset = 0;
4844
4845 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
4846 pPMEMInfo->pmem_fd = 0;
4847 bufHdr->pPlatformPrivate = pPlatformList;
4848
4849 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
4850 m_pmem_info[i].pmem_fd = pmem_fd;
4851#ifdef USE_ION
4852 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
4853 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
4854 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
4855#endif
4856
4857 /*Create a mapping between buffers*/
4858 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
4859 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
4860 &drv_ctx.ptr_outputbuffer[i];
4861 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
4862 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4863 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
4864
4865 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
4866 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
4867 drv_ctx.ptr_outputbuffer[i].bufferaddr);
4868 // Move the buffer and buffer header pointers
4869 bufHdr++;
4870 pPMEMInfo++;
4871 pPlatformEntry++;
4872 pPlatformList++;
4873 }
4874 } else {
4875 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
4876 m_out_mem_ptr, pPtr);
4877 if (m_out_mem_ptr) {
4878 free(m_out_mem_ptr);
4879 m_out_mem_ptr = NULL;
4880 }
4881 if (pPtr) {
4882 free(pPtr);
4883 pPtr = NULL;
4884 }
4885 if (drv_ctx.ptr_outputbuffer) {
4886 free(drv_ctx.ptr_outputbuffer);
4887 drv_ctx.ptr_outputbuffer = NULL;
4888 }
4889 if (drv_ctx.ptr_respbuffer) {
4890 free(drv_ctx.ptr_respbuffer);
4891 drv_ctx.ptr_respbuffer = NULL;
4892 }
4893#ifdef USE_ION
4894 if (drv_ctx.op_buf_ion_info) {
4895 DEBUG_PRINT_LOW("\n Free o/p ion context");
4896 free(drv_ctx.op_buf_ion_info);
4897 drv_ctx.op_buf_ion_info = NULL;
4898 }
4899#endif
4900 eRet = OMX_ErrorInsufficientResources;
4901 }
4902 if (eRet == OMX_ErrorNone)
4903 eRet = allocate_extradata();
4904 }
4905
4906 for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4907 if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4908 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
4909 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004910 }
4911 }
Arun Menon906de572013-06-18 17:01:40 -07004912
4913 if (eRet == OMX_ErrorNone) {
4914 if (i < drv_ctx.op_buf.actualcount) {
4915 struct v4l2_buffer buf;
4916 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4917 int rc;
4918 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4919
4920 drv_ctx.ptr_outputbuffer[i].buffer_len =
4921 drv_ctx.op_buf.buffer_size;
4922
4923 *bufferHdr = (m_out_mem_ptr + i );
4924 if (secure_mode) {
4925 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4926 }
4927 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
4928
4929 buf.index = i;
4930 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4931 buf.memory = V4L2_MEMORY_USERPTR;
4932 plane[0].length = drv_ctx.op_buf.buffer_size;
4933 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4934 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004935#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004936 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004937#endif
Arun Menon906de572013-06-18 17:01:40 -07004938 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4939 plane[0].data_offset = 0;
4940 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4941 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4942 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4943 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 -07004944#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07004945 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004946#endif
Arun Menon906de572013-06-18 17:01:40 -07004947 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4948 plane[extra_idx].data_offset = 0;
4949 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4950 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
4951 return OMX_ErrorBadParameter;
4952 }
4953 buf.m.planes = plane;
4954 buf.length = drv_ctx.num_planes;
4955 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
4956 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4957 if (rc) {
4958 /*TODO: How to handle this case */
4959 return OMX_ErrorInsufficientResources;
4960 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004961
Arun Menon906de572013-06-18 17:01:40 -07004962 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
4963 enum v4l2_buf_type buf_type;
4964 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4965 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
4966 if (rc) {
4967 return OMX_ErrorInsufficientResources;
4968 } else {
4969 streaming[CAPTURE_PORT] = true;
4970 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4971 }
4972 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004973
Arun Menon906de572013-06-18 17:01:40 -07004974 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
4975 (*bufferHdr)->pAppPrivate = appData;
4976 BITMASK_SET(&m_out_bm_count,i);
4977 } else {
4978 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
4979 eRet = OMX_ErrorInsufficientResources;
4980 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004981 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004982
Arun Menon906de572013-06-18 17:01:40 -07004983 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004984}
4985
4986
4987// AllocateBuffer -- API Call
4988/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07004989 FUNCTION
4990 omx_vdec::AllocateBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07004991
Arun Menon906de572013-06-18 17:01:40 -07004992 DESCRIPTION
4993 Returns zero if all the buffers released..
Shalaj Jain273b3e02012-06-22 19:08:03 -07004994
Arun Menon906de572013-06-18 17:01:40 -07004995 PARAMETERS
4996 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07004997
Arun Menon906de572013-06-18 17:01:40 -07004998 RETURN VALUE
4999 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005000
Arun Menon906de572013-06-18 17:01:40 -07005001 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005002OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005003 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5004 OMX_IN OMX_U32 port,
5005 OMX_IN OMX_PTR appData,
5006 OMX_IN OMX_U32 bytes)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005007{
5008 unsigned i = 0;
5009 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5010
5011 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
Arun Menon906de572013-06-18 17:01:40 -07005012 if (m_state == OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005013 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5014 return OMX_ErrorInvalidState;
5015 }
5016
Arun Menon906de572013-06-18 17:01:40 -07005017 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5018 if (arbitrary_bytes) {
5019 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5020 } else {
5021 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5022 }
5023 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005024 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5025 appData,bytes);
Arun Menon906de572013-06-18 17:01:40 -07005026 } else {
5027 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5028 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005029 }
5030 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
Arun Menon906de572013-06-18 17:01:40 -07005031 if (eRet == OMX_ErrorNone) {
5032 if (allocate_done()) {
5033 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005034 // Send the callback now
5035 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5036 post_event(OMX_CommandStateSet,OMX_StateIdle,
Arun Menon906de572013-06-18 17:01:40 -07005037 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005038 }
5039 }
Arun Menon906de572013-06-18 17:01:40 -07005040 if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5041 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5042 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5043 post_event(OMX_CommandPortEnable,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005044 OMX_CORE_INPUT_PORT_INDEX,
5045 OMX_COMPONENT_GENERATE_EVENT);
Arun Menon906de572013-06-18 17:01:40 -07005046 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005047 }
Arun Menon906de572013-06-18 17:01:40 -07005048 if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5049 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5050 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005051 post_event(OMX_CommandPortEnable,
Arun Menon906de572013-06-18 17:01:40 -07005052 OMX_CORE_OUTPUT_PORT_INDEX,
5053 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005054 }
5055 }
5056 }
5057 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5058 return eRet;
5059}
5060
5061// Free Buffer - API call
5062/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005063 FUNCTION
5064 omx_vdec::FreeBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005065
Arun Menon906de572013-06-18 17:01:40 -07005066 DESCRIPTION
Shalaj Jain273b3e02012-06-22 19:08:03 -07005067
Arun Menon906de572013-06-18 17:01:40 -07005068 PARAMETERS
5069 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005070
Arun Menon906de572013-06-18 17:01:40 -07005071 RETURN VALUE
5072 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005073
Arun Menon906de572013-06-18 17:01:40 -07005074 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005075OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005076 OMX_IN OMX_U32 port,
5077 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005078{
5079 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5080 unsigned int nPortIndex;
5081 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5082
Arun Menon906de572013-06-18 17:01:40 -07005083 if (m_state == OMX_StateIdle &&
5084 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005085 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
Arun Menon906de572013-06-18 17:01:40 -07005086 } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5087 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005088 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Arun Menon906de572013-06-18 17:01:40 -07005089 } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
5090 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
5091 (port == OMX_CORE_OUTPUT_PORT_INDEX &&
5092 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
Arun Menon9f098152013-05-08 13:53:54 -07005093 DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port);
Arun Menon906de572013-06-18 17:01:40 -07005094 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005095 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5096 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005097 OMX_ErrorPortUnpopulated,
5098 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005099
5100 return OMX_ErrorIncorrectStateOperation;
Arun Menon906de572013-06-18 17:01:40 -07005101 } else if (m_state != OMX_StateInvalid) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005102 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5103 post_event(OMX_EventError,
Arun Menon906de572013-06-18 17:01:40 -07005104 OMX_ErrorPortUnpopulated,
5105 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005106 }
5107
Arun Menon906de572013-06-18 17:01:40 -07005108 if (port == OMX_CORE_INPUT_PORT_INDEX) {
5109 /*Check if arbitrary bytes*/
5110 if (!arbitrary_bytes && !input_use_buffer)
5111 nPortIndex = buffer - m_inp_mem_ptr;
5112 else
5113 nPortIndex = buffer - m_inp_heap_ptr;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005114
5115 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
Arun Menon906de572013-06-18 17:01:40 -07005116 if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5117 // Clear the bit associated with it.
5118 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5119 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5120 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005121
Arun Menon906de572013-06-18 17:01:40 -07005122 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5123 if (m_phdr_pmem_ptr)
5124 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5125 } else {
5126 if (arbitrary_bytes) {
5127 if (m_phdr_pmem_ptr)
5128 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5129 else
5130 free_input_buffer(nPortIndex,NULL);
5131 } else
5132 free_input_buffer(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005133 }
Arun Menon906de572013-06-18 17:01:40 -07005134 m_inp_bPopulated = OMX_FALSE;
Surajit Podder12aefac2013-08-06 18:43:32 +05305135 if(release_input_done())
5136 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
Arun Menon906de572013-06-18 17:01:40 -07005137 /*Free the Buffer Header*/
5138 if (release_input_done()) {
5139 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5140 free_input_buffer_header();
5141 }
5142 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005143 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5144 eRet = OMX_ErrorBadPortIndex;
5145 }
5146
Arun Menon906de572013-06-18 17:01:40 -07005147 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5148 && release_input_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005149 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5150 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5151 post_event(OMX_CommandPortDisable,
Arun Menon906de572013-06-18 17:01:40 -07005152 OMX_CORE_INPUT_PORT_INDEX,
5153 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005154 }
Arun Menon906de572013-06-18 17:01:40 -07005155 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005156 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005157 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Arun Menon906de572013-06-18 17:01:40 -07005158 if (nPortIndex < drv_ctx.op_buf.actualcount) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005159 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5160 // Clear the bit associated with it.
5161 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5162 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005163 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005164
Surajit Podder12aefac2013-08-06 18:43:32 +05305165 if(release_output_done()) {
5166 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
5167 }
Arun Menon906de572013-06-18 17:01:40 -07005168 if (release_output_done()) {
5169 free_output_buffer_header();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005170 }
Arun Menon906de572013-06-18 17:01:40 -07005171 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005172 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5173 eRet = OMX_ErrorBadPortIndex;
5174 }
Arun Menon906de572013-06-18 17:01:40 -07005175 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5176 && release_output_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005177 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5178
Arun Menon906de572013-06-18 17:01:40 -07005179 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5180 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005181#ifdef _ANDROID_ICS_
Arun Menon906de572013-06-18 17:01:40 -07005182 if (m_enable_android_native_buffers) {
5183 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5184 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5185 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005186#endif
5187
Arun Menon906de572013-06-18 17:01:40 -07005188 post_event(OMX_CommandPortDisable,
5189 OMX_CORE_OUTPUT_PORT_INDEX,
5190 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005191 }
Arun Menon906de572013-06-18 17:01:40 -07005192 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005193 eRet = OMX_ErrorBadPortIndex;
5194 }
Arun Menon906de572013-06-18 17:01:40 -07005195 if ((eRet == OMX_ErrorNone) &&
5196 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5197 if (release_done()) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005198 // Send the callback now
5199 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5200 post_event(OMX_CommandStateSet, OMX_StateLoaded,
Arun Menon906de572013-06-18 17:01:40 -07005201 OMX_COMPONENT_GENERATE_EVENT);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005202 }
5203 }
5204 return eRet;
5205}
5206
5207
5208/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005209 FUNCTION
5210 omx_vdec::EmptyThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005211
Arun Menon906de572013-06-18 17:01:40 -07005212 DESCRIPTION
5213 This routine is used to push the encoded video frames to
5214 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005215
Arun Menon906de572013-06-18 17:01:40 -07005216 PARAMETERS
5217 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005218
Arun Menon906de572013-06-18 17:01:40 -07005219 RETURN VALUE
5220 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005221
Arun Menon906de572013-06-18 17:01:40 -07005222 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005223OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005224 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005225{
Arun Menon906de572013-06-18 17:01:40 -07005226 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5227 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005228
Arun Menon906de572013-06-18 17:01:40 -07005229 if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5230 codec_config_flag = true;
5231 DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5232 } else {
5233 codec_config_flag = false;
5234 }
Praneeth Paladugu80dd03b2013-05-22 16:57:42 -07005235
Arun Menon906de572013-06-18 17:01:40 -07005236 if (m_state == OMX_StateInvalid) {
5237 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5238 return OMX_ErrorInvalidState;
5239 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005240
Arun Menon906de572013-06-18 17:01:40 -07005241 if (buffer == NULL) {
5242 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5243 return OMX_ErrorBadParameter;
5244 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005245
Arun Menon906de572013-06-18 17:01:40 -07005246 if (!m_inp_bEnabled) {
5247 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5248 return OMX_ErrorIncorrectStateOperation;
5249 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005250
Arun Menon906de572013-06-18 17:01:40 -07005251 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
5252 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
5253 return OMX_ErrorBadPortIndex;
5254 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005255
5256#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005257 if (iDivXDrmDecrypt) {
5258 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5259 if (drmErr != OMX_ErrorNone) {
5260 // this error can be ignored
5261 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5262 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005263 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005264#endif //_ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005265 if (perf_flag) {
5266 if (!latency) {
5267 dec_time.stop();
5268 latency = dec_time.processing_time_us();
5269 dec_time.start();
5270 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005271 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005272
Arun Menon906de572013-06-18 17:01:40 -07005273 if (arbitrary_bytes) {
5274 nBufferIndex = buffer - m_inp_heap_ptr;
5275 } else {
5276 if (input_use_buffer == true) {
5277 nBufferIndex = buffer - m_inp_heap_ptr;
5278 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5279 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5280 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5281 buffer = &m_inp_mem_ptr[nBufferIndex];
5282 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
5283 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5284 } else {
5285 nBufferIndex = buffer - m_inp_mem_ptr;
5286 }
5287 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005288
Arun Menon906de572013-06-18 17:01:40 -07005289 if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
5290 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5291 return OMX_ErrorBadParameter;
5292 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005293
Arun Menon906de572013-06-18 17:01:40 -07005294 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5295 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5296 if (arbitrary_bytes) {
5297 post_event ((unsigned)hComp,(unsigned)buffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005298 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
Arun Menon906de572013-06-18 17:01:40 -07005299 } else {
5300 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5301 set_frame_rate(buffer->nTimeStamp);
5302 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5303 }
5304 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005305}
5306
5307/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005308 FUNCTION
5309 omx_vdec::empty_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005310
Arun Menon906de572013-06-18 17:01:40 -07005311 DESCRIPTION
5312 This routine is used to push the encoded video frames to
5313 the video decoder.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005314
Arun Menon906de572013-06-18 17:01:40 -07005315 PARAMETERS
5316 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005317
Arun Menon906de572013-06-18 17:01:40 -07005318 RETURN VALUE
5319 OMX Error None if everything went successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005320
Arun Menon906de572013-06-18 17:01:40 -07005321 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005322OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005323 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005324{
Arun Menon906de572013-06-18 17:01:40 -07005325 int push_cnt = 0,i=0;
5326 unsigned nPortIndex = 0;
5327 OMX_ERRORTYPE ret = OMX_ErrorNone;
5328 struct vdec_input_frameinfo frameinfo;
5329 struct vdec_bufferpayload *temp_buffer;
5330 struct vdec_seqheader seq_header;
5331 bool port_setting_changed = true;
5332 bool not_coded_vop = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005333
Arun Menon906de572013-06-18 17:01:40 -07005334 /*Should we generate a Aync error event*/
5335 if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
5336 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5337 return OMX_ErrorBadParameter;
5338 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005339
Arun Menon906de572013-06-18 17:01:40 -07005340 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005341
Arun Menon906de572013-06-18 17:01:40 -07005342 if (nPortIndex > drv_ctx.ip_buf.actualcount) {
5343 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5344 nPortIndex);
5345 return OMX_ErrorBadParameter;
5346 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005347
Arun Menon906de572013-06-18 17:01:40 -07005348 pending_input_buffers++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005349
Arun Menon906de572013-06-18 17:01:40 -07005350 /* return zero length and not an EOS buffer */
5351 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5352 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
5353 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5354 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5355 OMX_COMPONENT_GENERATE_EBD);
5356 return OMX_ErrorNone;
5357 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005358
5359
Arun Menon906de572013-06-18 17:01:40 -07005360 if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5361 mp4StreamType psBits;
5362 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5363 psBits.numBytes = buffer->nFilledLen;
5364 mp4_headerparser.parseHeader(&psBits);
5365 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5366 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5367 if (not_coded_vop) {
5368 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
5369 buffer->nFilledLen,frame_count);
5370 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
5371 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5372 not_coded_vop = false;
5373 buffer->nFilledLen = 0;
5374 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005375 }
5376 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005377
Arun Menon906de572013-06-18 17:01:40 -07005378 if (input_flush_progress == true
Shalaj Jain273b3e02012-06-22 19:08:03 -07005379
Arun Menon906de572013-06-18 17:01:40 -07005380 || not_coded_vop
Shalaj Jain273b3e02012-06-22 19:08:03 -07005381
Arun Menon906de572013-06-18 17:01:40 -07005382 ) {
5383 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5384 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5385 OMX_COMPONENT_GENERATE_EBD);
5386 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005387 }
5388
Arun Menon906de572013-06-18 17:01:40 -07005389 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005390
Arun Menon906de572013-06-18 17:01:40 -07005391 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) {
5392 return OMX_ErrorBadParameter;
5393 }
5394 /* If its first frame, H264 codec and reject is true, then parse the nal
5395 and get the profile. Based on this, reject the clip playback */
5396 if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
5397 m_reject_avc_1080p_mp) {
5398 first_frame = 1;
5399 DEBUG_PRINT_ERROR("\nParse nal to get the profile");
5400 h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
5401 NALU_TYPE_SPS);
5402 m_profile = h264_parser->get_profile();
5403 ret = is_video_session_supported();
5404 if (ret) {
5405 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
5406 post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
5407 /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
5408 m_state = OMX_StateInvalid;
5409 return OMX_ErrorNone;
5410 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005411 }
5412
Arun Menon906de572013-06-18 17:01:40 -07005413 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5414 /*for use buffer we need to memcpy the data*/
5415 temp_buffer->buffer_len = buffer->nFilledLen;
5416
5417 if (input_use_buffer) {
5418 if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5419 if (arbitrary_bytes) {
5420 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5421 } else {
5422 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5423 buffer->nFilledLen);
5424 }
5425 } else {
5426 return OMX_ErrorBadParameter;
5427 }
5428
5429 }
5430
5431 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5432 frameinfo.client_data = (void *) buffer;
5433 frameinfo.datalen = temp_buffer->buffer_len;
5434 frameinfo.flags = 0;
5435 frameinfo.offset = buffer->nOffset;
5436 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5437 frameinfo.pmem_offset = temp_buffer->offset;
5438 frameinfo.timestamp = buffer->nTimeStamp;
5439 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5440 DEBUG_PRINT_LOW("ETB: dmx enabled");
5441 if (m_demux_entries == 0) {
5442 extract_demux_addr_offsets(buffer);
5443 }
5444
5445 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
5446 handle_demux_data(buffer);
5447 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5448 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5449 } else {
5450 frameinfo.desc_addr = NULL;
5451 frameinfo.desc_size = 0;
5452 }
5453 if (!arbitrary_bytes) {
5454 frameinfo.flags |= buffer->nFlags;
5455 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005456
5457#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005458 if (m_debug_timestamp) {
5459 if (arbitrary_bytes) {
5460 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5461 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5462 } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5463 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5464 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5465 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005466 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005467#endif
5468
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005469log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005470
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005471if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
Arun Menon906de572013-06-18 17:01:40 -07005472 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5473 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5474 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005475
Arun Menon906de572013-06-18 17:01:40 -07005476 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5477 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5478 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5479 h264_scratch.nFilledLen = 0;
5480 nal_count = 0;
5481 look_ahead_nal = false;
5482 frame_count = 0;
5483 if (m_frame_parser.mutils)
5484 m_frame_parser.mutils->initialize_frame_checking_environment();
5485 m_frame_parser.flush();
5486 h264_last_au_ts = LLONG_MAX;
5487 h264_last_au_flags = 0;
5488 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5489 m_demux_entries = 0;
5490 }
5491 struct v4l2_buffer buf;
5492 struct v4l2_plane plane;
5493 memset( (void *)&buf, 0, sizeof(buf));
5494 memset( (void *)&plane, 0, sizeof(plane));
5495 int rc;
5496 unsigned long print_count;
5497 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07005498 buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
Arun Menon906de572013-06-18 17:01:40 -07005499 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
5500 }
5501 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5502 buf.index = nPortIndex;
5503 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5504 buf.memory = V4L2_MEMORY_USERPTR;
5505 plane.bytesused = temp_buffer->buffer_len;
5506 plane.length = drv_ctx.ip_buf.buffer_size;
5507 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5508 (unsigned long)temp_buffer->offset;
5509 plane.reserved[0] = temp_buffer->pmem_fd;
5510 plane.reserved[1] = temp_buffer->offset;
5511 plane.data_offset = 0;
5512 buf.m.planes = &plane;
5513 buf.length = 1;
5514 if (frameinfo.timestamp >= LLONG_MAX) {
5515 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5516 }
5517 //assumption is that timestamp is in milliseconds
5518 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5519 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
5520 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5521 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005522
Arun Menon906de572013-06-18 17:01:40 -07005523 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5524 if (rc) {
5525 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5526 return OMX_ErrorHardware;
5527 }
5528 if (!streaming[OUTPUT_PORT]) {
5529 enum v4l2_buf_type buf_type;
5530 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005531
Arun Menon906de572013-06-18 17:01:40 -07005532 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005533 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
Arun Menon906de572013-06-18 17:01:40 -07005534 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5535 if (!ret) {
5536 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
5537 streaming[OUTPUT_PORT] = true;
5538 } else {
5539 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
5540 DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
5541 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5542 OMX_COMPONENT_GENERATE_EBD);
5543 return OMX_ErrorBadParameter;
5544 }
5545 }
5546 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5547 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5548 time_stamp_dts.insert_timestamp(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005549
Arun Menon906de572013-06-18 17:01:40 -07005550 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005551}
5552
5553/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005554 FUNCTION
5555 omx_vdec::FillThisBuffer
Shalaj Jain273b3e02012-06-22 19:08:03 -07005556
Arun Menon906de572013-06-18 17:01:40 -07005557 DESCRIPTION
5558 IL client uses this method to release the frame buffer
5559 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005560
Arun Menon906de572013-06-18 17:01:40 -07005561 PARAMETERS
5562 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005563
Arun Menon906de572013-06-18 17:01:40 -07005564 RETURN VALUE
5565 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005566
Arun Menon906de572013-06-18 17:01:40 -07005567 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005568OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005569 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005570{
Arun Menonbdb80b02013-08-12 17:45:54 -07005571#ifdef META_DATA_MODE_SUPPORTED
5572 if (dynamic_buf_mode) {
5573 private_handle_t *handle = NULL;
5574 struct VideoDecoderOutputMetaData *meta;
5575 OMX_U8 *buff = NULL;
5576 unsigned int nPortIndex = 0;
5577
5578 if (!buffer || !buffer->pBuffer) {
5579 DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
5580 return OMX_ErrorBadParameter;
5581 }
5582
5583 //get the buffer type and fd info
5584 meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
5585 handle = (private_handle_t *)meta->pHandle;
5586 DEBUG_PRINT_LOW("FTB: buftype: %d bufhndl: %p", meta->eType, meta->pHandle);
5587
5588 //map the buffer handle based on the size set on output port definition.
5589 if (!secure_mode) {
5590 buff = (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
5591 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
5592 } else {
5593 buff = (OMX_U8*) buffer;
5594 }
5595
5596 //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
5597 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
5598 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
5599 drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
5600 drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = buff;
5601 drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
5602 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
5603 buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
5604 drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5605 }
5606#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07005607
Arun Menon906de572013-06-18 17:01:40 -07005608 if (m_state == OMX_StateInvalid) {
5609 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5610 return OMX_ErrorInvalidState;
5611 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005612
Arun Menon906de572013-06-18 17:01:40 -07005613 if (!m_out_bEnabled) {
5614 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5615 return OMX_ErrorIncorrectStateOperation;
5616 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005617
Arun Menon906de572013-06-18 17:01:40 -07005618 if (buffer == NULL ||
5619 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) {
5620 return OMX_ErrorBadParameter;
5621 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005622
Arun Menon906de572013-06-18 17:01:40 -07005623 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
5624 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
5625 return OMX_ErrorBadPortIndex;
5626 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005627
Arun Menon906de572013-06-18 17:01:40 -07005628 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5629 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
5630 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005631}
5632/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005633 FUNCTION
5634 omx_vdec::fill_this_buffer_proxy
Shalaj Jain273b3e02012-06-22 19:08:03 -07005635
Arun Menon906de572013-06-18 17:01:40 -07005636 DESCRIPTION
5637 IL client uses this method to release the frame buffer
5638 after displaying them.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005639
Arun Menon906de572013-06-18 17:01:40 -07005640 PARAMETERS
5641 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005642
Arun Menon906de572013-06-18 17:01:40 -07005643 RETURN VALUE
5644 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07005645
Arun Menon906de572013-06-18 17:01:40 -07005646 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005647OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
Arun Menon906de572013-06-18 17:01:40 -07005648 OMX_IN OMX_HANDLETYPE hComp,
5649 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005650{
Arun Menon906de572013-06-18 17:01:40 -07005651 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5652 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5653 unsigned nPortIndex = 0;
5654 struct vdec_fillbuffer_cmd fillbuffer;
5655 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5656 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005657
Arun Menon906de572013-06-18 17:01:40 -07005658 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005659
Arun Menon906de572013-06-18 17:01:40 -07005660 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
5661 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005662
Arun Menon906de572013-06-18 17:01:40 -07005663 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5664 bufferAdd, bufferAdd->pBuffer);
5665 /*Return back the output buffer to client*/
5666 if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
5667 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5668 buffer->nFilledLen = 0;
5669 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5670 return OMX_ErrorNone;
5671 }
5672 pending_output_buffers++;
5673 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5674 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5675 if (ptr_respbuffer) {
5676 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5677 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005678
Arun Menon906de572013-06-18 17:01:40 -07005679 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5680 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5681 buffer->nFilledLen = 0;
5682 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5683 pending_output_buffers--;
5684 return OMX_ErrorBadParameter;
5685 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005686
Arun Menon906de572013-06-18 17:01:40 -07005687 int rc = 0;
5688 struct v4l2_buffer buf;
5689 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5690 memset( (void *)&buf, 0, sizeof(buf));
5691 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
5692 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005693
Arun Menon906de572013-06-18 17:01:40 -07005694 buf.index = nPortIndex;
5695 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5696 buf.memory = V4L2_MEMORY_USERPTR;
5697 plane[0].bytesused = buffer->nFilledLen;
5698 plane[0].length = drv_ctx.op_buf.buffer_size;
5699 plane[0].m.userptr =
5700 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5701 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5702 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5703 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5704 plane[0].data_offset = 0;
5705 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5706 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5707 plane[extra_idx].bytesused = 0;
5708 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5709 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 -07005710#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07005711 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005712#endif
Arun Menon906de572013-06-18 17:01:40 -07005713 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5714 plane[extra_idx].data_offset = 0;
5715 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5716 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5717 return OMX_ErrorBadParameter;
5718 }
5719 buf.m.planes = plane;
5720 buf.length = drv_ctx.num_planes;
Arun Menonbdb80b02013-08-12 17:45:54 -07005721 DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d\n",
5722 plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
5723
Arun Menon906de572013-06-18 17:01:40 -07005724 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5725 if (rc) {
5726 /*TODO: How to handle this case */
5727 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5728 }
Arun Menon906de572013-06-18 17:01:40 -07005729return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005730}
5731
5732/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005733 FUNCTION
5734 omx_vdec::SetCallbacks
Shalaj Jain273b3e02012-06-22 19:08:03 -07005735
Arun Menon906de572013-06-18 17:01:40 -07005736 DESCRIPTION
5737 Set the callbacks.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005738
Arun Menon906de572013-06-18 17:01:40 -07005739 PARAMETERS
5740 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005741
Arun Menon906de572013-06-18 17:01:40 -07005742 RETURN VALUE
5743 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005744
Arun Menon906de572013-06-18 17:01:40 -07005745 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005746OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005747 OMX_IN OMX_CALLBACKTYPE* callbacks,
5748 OMX_IN OMX_PTR appData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005749{
5750
Arun Menon906de572013-06-18 17:01:40 -07005751 m_cb = *callbacks;
5752 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5753 m_cb.EventHandler,m_cb.FillBufferDone);
5754 m_app_data = appData;
5755 return OMX_ErrorNotImplemented;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005756}
5757
5758/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005759 FUNCTION
5760 omx_vdec::ComponentDeInit
Shalaj Jain273b3e02012-06-22 19:08:03 -07005761
Arun Menon906de572013-06-18 17:01:40 -07005762 DESCRIPTION
5763 Destroys the component and release memory allocated to the heap.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005764
Arun Menon906de572013-06-18 17:01:40 -07005765 PARAMETERS
5766 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005767
Arun Menon906de572013-06-18 17:01:40 -07005768 RETURN VALUE
5769 OMX Error None if everything successful.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005770
Arun Menon906de572013-06-18 17:01:40 -07005771 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005772OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5773{
5774#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005775 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005776 delete iDivXDrmDecrypt;
5777 iDivXDrmDecrypt=NULL;
5778 }
5779#endif //_ANDROID_
5780
Shalaj Jain286b0062013-02-21 20:35:48 -08005781 unsigned i = 0;
Arun Menon906de572013-06-18 17:01:40 -07005782 if (OMX_StateLoaded != m_state) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005783 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
Arun Menon906de572013-06-18 17:01:40 -07005784 m_state);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005785 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
Arun Menon906de572013-06-18 17:01:40 -07005786 } else {
5787 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005788 }
5789
5790 /*Check if the output buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005791 if (m_out_mem_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005792 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005793 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
5794 free_output_buffer (&m_out_mem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005795 }
5796#ifdef _ANDROID_ICS_
5797 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5798#endif
5799 }
5800
5801 /*Check if the input buffers have to be cleaned up*/
Arun Menon906de572013-06-18 17:01:40 -07005802 if (m_inp_mem_ptr || m_inp_heap_ptr) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005803 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Arun Menon906de572013-06-18 17:01:40 -07005804 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5805 if (m_inp_mem_ptr)
5806 free_input_buffer (i,&m_inp_mem_ptr[i]);
5807 else
5808 free_input_buffer (i,NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005809 }
5810 }
5811 free_input_buffer_header();
5812 free_output_buffer_header();
Arun Menon906de572013-06-18 17:01:40 -07005813 if (h264_scratch.pBuffer) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005814 free(h264_scratch.pBuffer);
5815 h264_scratch.pBuffer = NULL;
5816 }
5817
Arun Menon906de572013-06-18 17:01:40 -07005818 if (h264_parser) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005819 delete h264_parser;
Arun Menon906de572013-06-18 17:01:40 -07005820 h264_parser = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005821 }
5822
Leena Winterrowddb9eaca2013-08-23 10:40:41 -07005823 if (m_frame_parser.mutils) {
5824 DEBUG_PRINT_LOW("\n Free utils parser");
5825 delete (m_frame_parser.mutils);
5826 m_frame_parser.mutils = NULL;
5827 }
5828
Arun Menon906de572013-06-18 17:01:40 -07005829 if (m_platform_list) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005830 free(m_platform_list);
5831 m_platform_list = NULL;
5832 }
Arun Menon906de572013-06-18 17:01:40 -07005833 if (m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005834 free(m_vendor_config.pData);
5835 m_vendor_config.pData = NULL;
5836 }
5837
5838 // Reset counters in mesg queues
5839 m_ftb_q.m_size=0;
5840 m_cmd_q.m_size=0;
5841 m_etb_q.m_size=0;
5842 m_ftb_q.m_read = m_ftb_q.m_write =0;
5843 m_cmd_q.m_read = m_cmd_q.m_write =0;
5844 m_etb_q.m_read = m_etb_q.m_write =0;
5845#ifdef _ANDROID_
Arun Menon906de572013-06-18 17:01:40 -07005846 if (m_debug_timestamp) {
5847 m_timestamp_list.reset_ts_list();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005848 }
5849#endif
5850
5851 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
5852 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
Arun Menon906de572013-06-18 17:01:40 -07005853 // NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005854 DEBUG_PRINT_HIGH("\n Close the driver instance");
Arun Menon906de572013-06-18 17:01:40 -07005855
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07005856 if (m_debug.infile) {
5857 fclose(m_debug.infile);
5858 m_debug.infile = NULL;
5859 }
5860 if (m_debug.outfile) {
5861 fclose(m_debug.outfile);
5862 m_debug.outfile = NULL;
5863 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005864#ifdef OUTPUT_EXTRADATA_LOG
Shalaj Jainaf08f302013-03-18 13:15:35 -07005865 if (outputExtradataFile)
5866 fclose (outputExtradataFile);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005867#endif
Arun Menon906de572013-06-18 17:01:40 -07005868 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
5869 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005870}
5871
5872/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005873 FUNCTION
5874 omx_vdec::UseEGLImage
Shalaj Jain273b3e02012-06-22 19:08:03 -07005875
Arun Menon906de572013-06-18 17:01:40 -07005876 DESCRIPTION
5877 OMX Use EGL Image method implementation <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005878
Arun Menon906de572013-06-18 17:01:40 -07005879 PARAMETERS
5880 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005881
Arun Menon906de572013-06-18 17:01:40 -07005882 RETURN VALUE
5883 Not Implemented error.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005884
Arun Menon906de572013-06-18 17:01:40 -07005885 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005886OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005887 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5888 OMX_IN OMX_U32 port,
5889 OMX_IN OMX_PTR appData,
5890 OMX_IN void* eglImage)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005891{
Arun Menon906de572013-06-18 17:01:40 -07005892 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
5893 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
5894 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005895
5896#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005897 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
5898 EGLint fd = -1, offset = 0,pmemPtr = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005899#else
Arun Menon906de572013-06-18 17:01:40 -07005900 int fd = -1, offset = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005901#endif
Arun Menon906de572013-06-18 17:01:40 -07005902 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
5903 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
5904 DEBUG_PRINT_ERROR("\n ");
5905 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005906#ifdef USE_EGL_IMAGE_GPU
Arun Menon906de572013-06-18 17:01:40 -07005907 if (m_display_id == NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005908 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
5909 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005910 }
5911 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
5912 eglGetProcAddress("eglQueryImageKHR");
5913 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
5914 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
5915 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005916#else //with OMX test app
5917 struct temp_egl {
5918 int pmem_fd;
5919 int offset;
5920 };
5921 struct temp_egl *temp_egl_id = NULL;
5922 void * pmemPtr = (void *) eglImage;
5923 temp_egl_id = (struct temp_egl *)eglImage;
Arun Menon906de572013-06-18 17:01:40 -07005924 if (temp_egl_id != NULL) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07005925 fd = temp_egl_id->pmem_fd;
5926 offset = temp_egl_id->offset;
5927 }
5928#endif
5929 if (fd < 0) {
5930 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
5931 return OMX_ErrorInsufficientResources;
Arun Menon906de572013-06-18 17:01:40 -07005932 }
5933 pmem_info.pmem_fd = (OMX_U32) fd;
5934 pmem_info.offset = (OMX_U32) offset;
5935 pmem_entry.entry = (void *) &pmem_info;
5936 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5937 pmem_list.entryList = &pmem_entry;
5938 pmem_list.nEntries = 1;
5939 ouput_egl_buffers = true;
5940 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
5941 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
5942 (OMX_U8 *)pmemPtr)) {
5943 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
5944 return OMX_ErrorInsufficientResources;
5945 }
5946 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005947}
5948
5949/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07005950 FUNCTION
5951 omx_vdec::ComponentRoleEnum
Shalaj Jain273b3e02012-06-22 19:08:03 -07005952
Arun Menon906de572013-06-18 17:01:40 -07005953 DESCRIPTION
5954 OMX Component Role Enum method implementation.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005955
Arun Menon906de572013-06-18 17:01:40 -07005956 PARAMETERS
5957 <TBD>.
Shalaj Jain273b3e02012-06-22 19:08:03 -07005958
Arun Menon906de572013-06-18 17:01:40 -07005959 RETURN VALUE
5960 OMX Error None if everything is successful.
5961 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005962OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07005963 OMX_OUT OMX_U8* role,
5964 OMX_IN OMX_U32 index)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005965{
Arun Menon906de572013-06-18 17:01:40 -07005966 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005967
Arun Menon906de572013-06-18 17:01:40 -07005968 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
5969 if ((0 == index) && role) {
5970 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
5971 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5972 } else {
5973 eRet = OMX_ErrorNoMore;
5974 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005975 }
Arun Menon906de572013-06-18 17:01:40 -07005976 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
5977 if ((0 == index) && role) {
5978 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
5979 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5980 } else {
5981 eRet = OMX_ErrorNoMore;
5982 }
5983 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
5984 if ((0 == index) && role) {
5985 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
5986 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
5987 } else {
5988 DEBUG_PRINT_LOW("\n No more roles \n");
5989 eRet = OMX_ErrorNoMore;
5990 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005991 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005992
Arun Menon906de572013-06-18 17:01:40 -07005993 else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
5994 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
5995 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07005996
Shalaj Jain273b3e02012-06-22 19:08:03 -07005997 {
Arun Menon906de572013-06-18 17:01:40 -07005998 if ((0 == index) && role) {
5999 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6000 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6001 } else {
6002 DEBUG_PRINT_LOW("\n No more roles \n");
6003 eRet = OMX_ErrorNoMore;
6004 }
6005 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6006 if ((0 == index) && role) {
6007 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6008 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6009 } else {
6010 DEBUG_PRINT_LOW("\n No more roles \n");
6011 eRet = OMX_ErrorNoMore;
6012 }
6013 } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6014 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6015 ) {
6016 if ((0 == index) && role) {
6017 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6018 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6019 } else {
6020 DEBUG_PRINT_LOW("\n No more roles \n");
6021 eRet = OMX_ErrorNoMore;
6022 }
6023 } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
6024 if ((0 == index) && role) {
6025 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6026 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6027 } else {
6028 DEBUG_PRINT_LOW("\n No more roles \n");
6029 eRet = OMX_ErrorNoMore;
6030 }
6031 } else {
6032 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6033 eRet = OMX_ErrorInvalidComponentName;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006034 }
Arun Menon906de572013-06-18 17:01:40 -07006035 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006036}
6037
6038
6039
6040
6041/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006042 FUNCTION
6043 omx_vdec::AllocateDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006044
Arun Menon906de572013-06-18 17:01:40 -07006045 DESCRIPTION
6046 Checks if entire buffer pool is allocated by IL Client or not.
6047 Need this to move to IDLE state.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006048
Arun Menon906de572013-06-18 17:01:40 -07006049 PARAMETERS
6050 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006051
Arun Menon906de572013-06-18 17:01:40 -07006052 RETURN VALUE
6053 true/false.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006054
Arun Menon906de572013-06-18 17:01:40 -07006055 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006056bool omx_vdec::allocate_done(void)
6057{
Arun Menon906de572013-06-18 17:01:40 -07006058 bool bRet = false;
6059 bool bRet_In = false;
6060 bool bRet_Out = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006061
Arun Menon906de572013-06-18 17:01:40 -07006062 bRet_In = allocate_input_done();
6063 bRet_Out = allocate_output_done();
Shalaj Jain273b3e02012-06-22 19:08:03 -07006064
Arun Menon906de572013-06-18 17:01:40 -07006065 if (bRet_In && bRet_Out) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006066 bRet = true;
6067 }
Arun Menon906de572013-06-18 17:01:40 -07006068
6069 return bRet;
6070}
6071/* ======================================================================
6072 FUNCTION
6073 omx_vdec::AllocateInputDone
6074
6075 DESCRIPTION
6076 Checks if I/P buffer pool is allocated by IL Client or not.
6077
6078 PARAMETERS
6079 None.
6080
6081 RETURN VALUE
6082 true/false.
6083
6084 ========================================================================== */
6085bool omx_vdec::allocate_input_done(void)
6086{
6087 bool bRet = false;
6088 unsigned i=0;
6089
6090 if (m_inp_mem_ptr == NULL) {
6091 return bRet;
6092 }
6093 if (m_inp_mem_ptr ) {
6094 for (; i<drv_ctx.ip_buf.actualcount; i++) {
6095 if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6096 break;
6097 }
6098 }
6099 }
6100 if (i == drv_ctx.ip_buf.actualcount) {
6101 bRet = true;
6102 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6103 }
6104 if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6105 m_inp_bPopulated = OMX_TRUE;
6106 }
6107 return bRet;
6108}
6109/* ======================================================================
6110 FUNCTION
6111 omx_vdec::AllocateOutputDone
6112
6113 DESCRIPTION
6114 Checks if entire O/P buffer pool is allocated by IL Client or not.
6115
6116 PARAMETERS
6117 None.
6118
6119 RETURN VALUE
6120 true/false.
6121
6122 ========================================================================== */
6123bool omx_vdec::allocate_output_done(void)
6124{
6125 bool bRet = false;
6126 unsigned j=0;
6127
6128 if (m_out_mem_ptr == NULL) {
6129 return bRet;
6130 }
6131
6132 if (m_out_mem_ptr) {
6133 for (; j < drv_ctx.op_buf.actualcount; j++) {
6134 if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6135 break;
6136 }
6137 }
6138 }
6139
6140 if (j == drv_ctx.op_buf.actualcount) {
6141 bRet = true;
6142 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6143 if (m_out_bEnabled)
6144 m_out_bPopulated = OMX_TRUE;
6145 }
6146
6147 return bRet;
6148}
6149
6150/* ======================================================================
6151 FUNCTION
6152 omx_vdec::ReleaseDone
6153
6154 DESCRIPTION
6155 Checks if IL client has released all the buffers.
6156
6157 PARAMETERS
6158 None.
6159
6160 RETURN VALUE
6161 true/false
6162
6163 ========================================================================== */
6164bool omx_vdec::release_done(void)
6165{
6166 bool bRet = false;
6167
6168 if (release_input_done()) {
6169 if (release_output_done()) {
6170 bRet = true;
6171 }
6172 }
6173 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006174}
6175
6176
6177/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006178 FUNCTION
6179 omx_vdec::ReleaseOutputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006180
Arun Menon906de572013-06-18 17:01:40 -07006181 DESCRIPTION
6182 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006183
Arun Menon906de572013-06-18 17:01:40 -07006184 PARAMETERS
6185 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006186
Arun Menon906de572013-06-18 17:01:40 -07006187 RETURN VALUE
6188 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006189
Arun Menon906de572013-06-18 17:01:40 -07006190 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006191bool omx_vdec::release_output_done(void)
6192{
Arun Menon906de572013-06-18 17:01:40 -07006193 bool bRet = false;
6194 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006195
Arun Menon906de572013-06-18 17:01:40 -07006196 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6197 if (m_out_mem_ptr) {
6198 for (; j < drv_ctx.op_buf.actualcount ; j++) {
6199 if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6200 break;
6201 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006202 }
Arun Menon906de572013-06-18 17:01:40 -07006203 if (j == drv_ctx.op_buf.actualcount) {
6204 m_out_bm_count = 0;
6205 bRet = true;
6206 }
6207 } else {
6208 m_out_bm_count = 0;
6209 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006210 }
Arun Menon906de572013-06-18 17:01:40 -07006211 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006212}
6213/* ======================================================================
Arun Menon906de572013-06-18 17:01:40 -07006214 FUNCTION
6215 omx_vdec::ReleaseInputDone
Shalaj Jain273b3e02012-06-22 19:08:03 -07006216
Arun Menon906de572013-06-18 17:01:40 -07006217 DESCRIPTION
6218 Checks if IL client has released all the buffers.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006219
Arun Menon906de572013-06-18 17:01:40 -07006220 PARAMETERS
6221 None.
Shalaj Jain273b3e02012-06-22 19:08:03 -07006222
Arun Menon906de572013-06-18 17:01:40 -07006223 RETURN VALUE
6224 true/false
Shalaj Jain273b3e02012-06-22 19:08:03 -07006225
Arun Menon906de572013-06-18 17:01:40 -07006226 ========================================================================== */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006227bool omx_vdec::release_input_done(void)
6228{
Arun Menon906de572013-06-18 17:01:40 -07006229 bool bRet = false;
6230 unsigned i=0,j=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006231
Arun Menon906de572013-06-18 17:01:40 -07006232 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6233 if (m_inp_mem_ptr) {
6234 for (; j<drv_ctx.ip_buf.actualcount; j++) {
6235 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6236 break;
6237 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006238 }
Arun Menon906de572013-06-18 17:01:40 -07006239 if (j==drv_ctx.ip_buf.actualcount) {
6240 bRet = true;
6241 }
6242 } else {
6243 bRet = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006244 }
Arun Menon906de572013-06-18 17:01:40 -07006245 return bRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006246}
6247
6248OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006249 OMX_BUFFERHEADERTYPE * buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006250{
Arun Menon906de572013-06-18 17:01:40 -07006251 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6252 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) {
6253 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6254 return OMX_ErrorBadParameter;
6255 } else if (output_flush_progress) {
6256 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6257 buffer->nFilledLen = 0;
6258 buffer->nTimeStamp = 0;
6259 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6260 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6261 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006262 }
6263
Arun Menon906de572013-06-18 17:01:40 -07006264 if (m_debug_extradata) {
6265 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
6266 DEBUG_PRINT_HIGH("\n");
6267 DEBUG_PRINT_HIGH("***************************************************\n");
6268 DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
6269 DEBUG_PRINT_HIGH("***************************************************\n");
6270 }
6271
6272 if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
6273 DEBUG_PRINT_HIGH("\n");
6274 DEBUG_PRINT_HIGH("***************************************************\n");
6275 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
6276 DEBUG_PRINT_HIGH("***************************************************\n");
6277 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006278 }
Praneeth Paladugu594e6822013-04-19 10:47:28 -07006279
6280
Arun Menon906de572013-06-18 17:01:40 -07006281 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6282 buffer, buffer->pBuffer);
6283 pending_output_buffers --;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006284
Arun Menonbdb80b02013-08-12 17:45:54 -07006285#ifdef META_DATA_MODE_SUPPORTED
6286 if (dynamic_buf_mode && !secure_mode) {
6287 unsigned int nPortIndex = 0;
6288 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
6289 munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
6290 drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
6291 }
6292#endif
6293
Arun Menon906de572013-06-18 17:01:40 -07006294 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6295 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6296 if (!output_flush_progress)
6297 post_event((unsigned)NULL, (unsigned)NULL,
6298 OMX_COMPONENT_GENERATE_EOS_DONE);
6299
6300 if (psource_frame) {
6301 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6302 psource_frame = NULL;
6303 }
6304 if (pdest_frame) {
6305 pdest_frame->nFilledLen = 0;
6306 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6307 (unsigned)NULL);
6308 pdest_frame = NULL;
6309 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006310 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006311
Arun Menon906de572013-06-18 17:01:40 -07006312 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
Jayasena Sangaraboina51230642013-08-21 18:02:13 -07006313 log_output_buffers(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006314
Arun Menon906de572013-06-18 17:01:40 -07006315 /* For use buffer we need to copy the data */
6316 if (!output_flush_progress) {
6317 /* This is the error check for non-recoverable errros */
6318 bool is_duplicate_ts_valid = true;
6319 bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006320
Arun Menon906de572013-06-18 17:01:40 -07006321 if (output_capability == V4L2_PIX_FMT_MPEG4 ||
6322 output_capability == V4L2_PIX_FMT_MPEG2 ||
6323 output_capability == V4L2_PIX_FMT_DIVX ||
6324 output_capability == V4L2_PIX_FMT_DIVX_311)
6325 is_duplicate_ts_valid = false;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07006326
Arun Menon906de572013-06-18 17:01:40 -07006327 if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
6328 bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
6329 if (mbaff) {
6330 is_interlaced = false;
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306331 }
Arun Menon906de572013-06-18 17:01:40 -07006332 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306333
Arun Menon906de572013-06-18 17:01:40 -07006334 if (buffer->nFilledLen > 0) {
6335 time_stamp_dts.get_next_timestamp(buffer,
6336 is_interlaced && is_duplicate_ts_valid);
6337 if (m_debug_timestamp) {
6338 {
6339 OMX_TICKS expected_ts = 0;
6340 m_timestamp_list.pop_min_ts(expected_ts);
6341 if (is_interlaced && is_duplicate_ts_valid) {
6342 m_timestamp_list.pop_min_ts(expected_ts);
6343 }
6344 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6345 buffer->nTimeStamp, expected_ts);
6346
6347 if (buffer->nTimeStamp != expected_ts) {
6348 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6349 }
6350 }
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306351 }
Arun Menon906de572013-06-18 17:01:40 -07006352 } else {
6353 m_inp_err_count++;
6354 time_stamp_dts.remove_time_stamp(
6355 buffer->nTimeStamp,
6356 is_interlaced && is_duplicate_ts_valid);
Rajeshwar Kurapaty46a24f02013-07-09 15:13:41 +05306357 }
Arun Menon906de572013-06-18 17:01:40 -07006358
6359
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006360 }
Arun Menon906de572013-06-18 17:01:40 -07006361 if (m_cb.FillBufferDone) {
6362 if (buffer->nFilledLen > 0) {
6363 handle_extradata(buffer);
6364 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6365 set_frame_rate(buffer->nTimeStamp);
6366 else if (arbitrary_bytes)
6367 adjust_timestamp(buffer->nTimeStamp);
6368 if (perf_flag) {
6369 if (!proc_frms) {
6370 dec_time.stop();
6371 latency = dec_time.processing_time_us() - latency;
6372 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6373 dec_time.start();
6374 fps_metrics.start();
6375 }
6376 proc_frms++;
6377 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6378 OMX_U64 proc_time = 0;
6379 fps_metrics.stop();
6380 proc_time = fps_metrics.processing_time_us();
6381 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07006382 proc_frms, (float)proc_time / 1e6,
6383 (float)(1e6 * proc_frms) / proc_time);
Arun Menon906de572013-06-18 17:01:40 -07006384 proc_frms = 0;
6385 }
6386 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006387
6388#ifdef OUTPUT_EXTRADATA_LOG
Arun Menon906de572013-06-18 17:01:40 -07006389 if (outputExtradataFile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006390
Arun Menon906de572013-06-18 17:01:40 -07006391 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6392 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6393 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6394 buffer->nFilledLen + 3)&(~3));
6395 while (p_extra &&
6396 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
6397 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6398 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6399 if (p_extra->eType == OMX_ExtraDataNone) {
6400 break;
6401 }
6402 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6403 }
6404 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006405#endif
Arun Menon906de572013-06-18 17:01:40 -07006406 }
6407 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6408 prev_ts = LLONG_MAX;
6409 rst_prev_ts = true;
6410 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006411
Arun Menon906de572013-06-18 17:01:40 -07006412 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6413 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6414 buffer->pPlatformPrivate)->entryList->entry;
6415 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Arun Menon906de572013-06-18 17:01:40 -07006416 OMX_BUFFERHEADERTYPE *il_buffer;
6417 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6418 if (il_buffer)
6419 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6420 else {
6421 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6422 return OMX_ErrorBadParameter;
6423 }
6424 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
6425 } else {
6426 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08006427 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006428
Arun Menon906de572013-06-18 17:01:40 -07006429 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006430}
6431
6432OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07006433 OMX_BUFFERHEADERTYPE* buffer)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006434{
6435
Arun Menon906de572013-06-18 17:01:40 -07006436 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006437 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
Arun Menon906de572013-06-18 17:01:40 -07006438 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006439 }
6440
6441 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
Arun Menon906de572013-06-18 17:01:40 -07006442 buffer, buffer->pBuffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006443 pending_input_buffers--;
6444
Arun Menon906de572013-06-18 17:01:40 -07006445 if (arbitrary_bytes) {
6446 if (pdest_frame == NULL && input_flush_progress == false) {
6447 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6448 pdest_frame = buffer;
6449 buffer->nFilledLen = 0;
6450 buffer->nTimeStamp = LLONG_MAX;
6451 push_input_buffer (hComp);
6452 } else {
6453 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6454 buffer->nFilledLen = 0;
6455 if (!m_input_free_q.insert_entry((unsigned)buffer,
6456 (unsigned)NULL, (unsigned)NULL)) {
6457 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6458 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006459 }
Arun Menon906de572013-06-18 17:01:40 -07006460 } else if (m_cb.EmptyBufferDone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006461 buffer->nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006462 if (input_use_buffer == true) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006463 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6464 }
6465 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6466 }
6467 return OMX_ErrorNone;
6468}
6469
Shalaj Jain273b3e02012-06-22 19:08:03 -07006470int omx_vdec::async_message_process (void *context, void* message)
6471{
Arun Menon906de572013-06-18 17:01:40 -07006472 omx_vdec* omx = NULL;
6473 struct vdec_msginfo *vdec_msg = NULL;
6474 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6475 struct v4l2_buffer *v4l2_buf_ptr = NULL;
6476 struct vdec_output_frameinfo *output_respbuf = NULL;
6477 int rc=1;
6478 if (context == NULL || message == NULL) {
6479 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6480 return -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006481 }
Arun Menon906de572013-06-18 17:01:40 -07006482 vdec_msg = (struct vdec_msginfo *)message;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006483
Arun Menon906de572013-06-18 17:01:40 -07006484 omx = reinterpret_cast<omx_vdec*>(context);
Vinay Kaliab9e98102013-04-02 19:31:43 -07006485
Arun Menon906de572013-06-18 17:01:40 -07006486 switch (vdec_msg->msgcode) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006487
Arun Menon906de572013-06-18 17:01:40 -07006488 case VDEC_MSG_EVT_HW_ERROR:
6489 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6490 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6491 break;
6492
6493 case VDEC_MSG_RESP_START_DONE:
6494 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6495 OMX_COMPONENT_GENERATE_START_DONE);
6496 break;
6497
6498 case VDEC_MSG_RESP_STOP_DONE:
6499 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6500 OMX_COMPONENT_GENERATE_STOP_DONE);
6501 break;
6502
6503 case VDEC_MSG_RESP_RESUME_DONE:
6504 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6505 OMX_COMPONENT_GENERATE_RESUME_DONE);
6506 break;
6507
6508 case VDEC_MSG_RESP_PAUSE_DONE:
6509 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6510 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6511 break;
6512
6513 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6514 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6515 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6516 break;
6517 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6518 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
6519 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6520 break;
6521 case VDEC_MSG_RESP_INPUT_FLUSHED:
6522 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6523
6524 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6525 vdec_msg->msgdata.input_frame_clientdata; */
6526
6527 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6528 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6529 if (omxhdr == NULL ||
6530 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) {
6531 omxhdr = NULL;
6532 vdec_msg->status_code = VDEC_S_EFATAL;
6533 }
6534 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
6535 DEBUG_PRINT_HIGH("Unsupported input");
6536 omx->omx_report_error ();
6537 }
6538 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6539 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
6540 }
6541 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6542 OMX_COMPONENT_GENERATE_EBD);
6543 break;
6544 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6545 int64_t *timestamp;
6546 timestamp = (int64_t *) malloc(sizeof(int64_t));
6547 if (timestamp) {
6548 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6549 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6550 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6551 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6552 vdec_msg->msgdata.output_frame.time_stamp);
6553 }
6554 break;
6555 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6556 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6557
6558 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6559 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6560 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6561 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6562 vdec_msg->msgdata.output_frame.pic_type);
6563
6564 if (omxhdr && omxhdr->pOutputPortPrivate &&
6565 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6566 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6567 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) {
Arun Menonbdb80b02013-08-12 17:45:54 -07006568#ifdef META_DATA_MODE_SUPPORTED
6569 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
6570 vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
6571 }
6572#endif
Arun Menon906de572013-06-18 17:01:40 -07006573 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) {
6574 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6575 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6576 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6577 omxhdr->nFlags = 0;
6578
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006579 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
Arun Menon906de572013-06-18 17:01:40 -07006580 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6581 //rc = -1;
6582 }
6583 if (omxhdr->nFilledLen) {
6584 omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
6585 }
6586 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
6587 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
6588 } else {
6589 omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6590 }
6591 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
6592 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6593 }
6594 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
6595 omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
6596 }
Arun Menonbdb80b02013-08-12 17:45:54 -07006597#ifdef META_DATA_MODE_SUPPORTED
6598 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
6599 DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
6600 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
6601 }
6602
6603 if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
6604 omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
6605 omxhdr->nOffset);
6606 }
6607#endif
Arun Menon906de572013-06-18 17:01:40 -07006608 if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
6609 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
Deva Ramasubramanianc1c7c122013-09-10 21:50:43 -07006610 !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
Praneeth Paladugu17364df2013-07-30 11:34:16 -07006611 omx->time_stamp_dts.remove_time_stamp(
6612 omxhdr->nTimeStamp,
6613 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6614 ?true:false);
Arun Menon906de572013-06-18 17:01:40 -07006615 omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
6616 OMX_COMPONENT_GENERATE_FTB);
6617 break;
6618 }
6619 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
6620 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
6621 }
6622 vdec_msg->msgdata.output_frame.bufferaddr =
6623 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6624 int format_notably_changed = 0;
6625 if (omxhdr->nFilledLen &&
6626 (omxhdr->nFilledLen != omx->prev_n_filled_len)) {
6627 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6628 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6629 DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
6630 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6631 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6632 format_notably_changed = 1;
6633 }
6634 }
6635 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6636 vdec_msg->msgdata.output_frame.framesize.left)
6637 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6638 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6639 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6640 if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
6641 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
6642 omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
6643 omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
6644 DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
6645 omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
6646 omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
6647 }
6648 DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
6649 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
6650 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006651 if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
6652 omx->drv_ctx.video_resolution.frame_width) {
6653 vdec_msg->msgdata.output_frame.framesize.left = 0;
6654 if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
6655 vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
6656 }
6657 }
6658 if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
6659 omx->drv_ctx.video_resolution.frame_height) {
6660 vdec_msg->msgdata.output_frame.framesize.top = 0;
6661 if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
6662 vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
6663 }
6664 }
6665 DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d\n",
6666 vdec_msg->msgdata.output_frame.framesize.left,
6667 vdec_msg->msgdata.output_frame.framesize.top,
6668 vdec_msg->msgdata.output_frame.framesize.right,
6669 vdec_msg->msgdata.output_frame.framesize.bottom,
6670 omx->drv_ctx.video_resolution.frame_width,
6671 omx->drv_ctx.video_resolution.frame_height);
Arun Menon906de572013-06-18 17:01:40 -07006672 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6673 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6674 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6675 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6676 format_notably_changed = 1;
6677 }
Jayasena Sangaraboina20283de2013-08-13 11:41:41 -07006678 DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d\n",
6679 vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
6680 vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
Arun Menon906de572013-06-18 17:01:40 -07006681 if (format_notably_changed) {
6682 if (omx->is_video_session_supported()) {
6683 omx->post_event (NULL, vdec_msg->status_code,
6684 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
6685 } else {
6686 if (!omx->client_buffers.update_buffer_req()) {
6687 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
6688 }
6689 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6690 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6691 }
6692 }
6693 if (omxhdr->nFilledLen)
6694 omx->prev_n_filled_len = omxhdr->nFilledLen;
6695
6696 output_respbuf = (struct vdec_output_frameinfo *)\
6697 omxhdr->pOutputPortPrivate;
6698 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6699 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6700 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
6701 output_respbuf->pic_type = PICTURE_TYPE_I;
6702 }
6703 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
6704 output_respbuf->pic_type = PICTURE_TYPE_P;
6705 }
6706 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6707 output_respbuf->pic_type = PICTURE_TYPE_B;
6708 }
6709
6710 if (omx->output_use_buffer)
6711 memcpy ( omxhdr->pBuffer, (void *)
6712 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6713 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6714 vdec_msg->msgdata.output_frame.len);
6715 } else
6716 omxhdr->nFilledLen = 0;
6717 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6718 OMX_COMPONENT_GENERATE_FBD);
6719 } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6720 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6721 OMX_COMPONENT_GENERATE_EOS_DONE);
6722 else
6723 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
6724 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6725 break;
6726 case VDEC_MSG_EVT_CONFIG_CHANGED:
6727 DEBUG_PRINT_HIGH("\n Port settings changed");
6728 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
6729 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6730 break;
6731 default:
6732 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006733 }
Arun Menon906de572013-06-18 17:01:40 -07006734 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006735}
6736
6737OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
Arun Menon906de572013-06-18 17:01:40 -07006738 OMX_HANDLETYPE hComp,
6739 OMX_BUFFERHEADERTYPE *buffer
6740 )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006741{
Arun Menon906de572013-06-18 17:01:40 -07006742 unsigned address,p2,id;
6743 DEBUG_PRINT_LOW("\n Empty this arbitrary");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006744
Arun Menon906de572013-06-18 17:01:40 -07006745 if (buffer == NULL) {
6746 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006747 }
Arun Menon906de572013-06-18 17:01:40 -07006748 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6749 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
6750 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
6751
6752 /* return zero length and not an EOS buffer */
6753 /* return buffer if input flush in progress */
6754 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6755 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
6756 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
6757 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6758 return OMX_ErrorNone;
6759 }
6760
6761 if (psource_frame == NULL) {
6762 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
6763 psource_frame = buffer;
6764 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
6765 push_input_buffer (hComp);
6766 } else {
6767 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
6768 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
6769 (unsigned)NULL)) {
6770 return OMX_ErrorBadParameter;
6771 }
6772 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006773
6774
Arun Menon906de572013-06-18 17:01:40 -07006775 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006776}
6777
6778OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6779{
Arun Menon906de572013-06-18 17:01:40 -07006780 unsigned address,p2,id;
6781 OMX_ERRORTYPE ret = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006782
Arun Menon906de572013-06-18 17:01:40 -07006783 if (pdest_frame == NULL || psource_frame == NULL) {
6784 /*Check if we have a destination buffer*/
6785 if (pdest_frame == NULL) {
6786 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
6787 if (m_input_free_q.m_size) {
6788 m_input_free_q.pop_entry(&address,&p2,&id);
6789 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6790 pdest_frame->nFilledLen = 0;
6791 pdest_frame->nTimeStamp = LLONG_MAX;
6792 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
6793 }
6794 }
6795
6796 /*Check if we have a destination buffer*/
6797 if (psource_frame == NULL) {
6798 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
6799 if (m_input_pending_q.m_size) {
6800 m_input_pending_q.pop_entry(&address,&p2,&id);
6801 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
6802 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6803 psource_frame->nTimeStamp);
6804 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6805 psource_frame->nFlags,psource_frame->nFilledLen);
6806
6807 }
6808 }
6809
Shalaj Jain273b3e02012-06-22 19:08:03 -07006810 }
6811
Arun Menon906de572013-06-18 17:01:40 -07006812 while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6813 switch (codec_type_parse) {
6814 case CODEC_TYPE_MPEG4:
6815 case CODEC_TYPE_H263:
6816 case CODEC_TYPE_MPEG2:
6817 ret = push_input_sc_codec(hComp);
6818 break;
6819 case CODEC_TYPE_H264:
6820 ret = push_input_h264(hComp);
6821 break;
6822 case CODEC_TYPE_VC1:
6823 ret = push_input_vc1(hComp);
6824 break;
6825 default:
6826 break;
6827 }
6828 if (ret != OMX_ErrorNone) {
6829 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
6830 omx_report_error ();
6831 break;
6832 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006833 }
6834
Arun Menon906de572013-06-18 17:01:40 -07006835 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006836}
6837
6838OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
6839{
Arun Menon906de572013-06-18 17:01:40 -07006840 OMX_U32 partial_frame = 1;
6841 OMX_BOOL generate_ebd = OMX_TRUE;
6842 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006843
Arun Menon906de572013-06-18 17:01:40 -07006844 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
6845 psource_frame,psource_frame->nTimeStamp);
6846 if (m_frame_parser.parse_sc_frame(psource_frame,
6847 pdest_frame,&partial_frame) == -1) {
6848 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
6849 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006850 }
Arun Menon906de572013-06-18 17:01:40 -07006851
6852 if (partial_frame == 0) {
6853 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
6854 pdest_frame->nFilledLen,psource_frame,frame_count);
6855
6856
6857 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
6858 /*First Parsed buffer will have only header Hence skip*/
6859 if (frame_count == 0) {
6860 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
6861
6862 if (codec_type_parse == CODEC_TYPE_MPEG4 ||
6863 codec_type_parse == CODEC_TYPE_DIVX) {
6864 mp4StreamType psBits;
6865 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
6866 psBits.numBytes = pdest_frame->nFilledLen;
6867 mp4_headerparser.parseHeader(&psBits);
6868 }
6869
6870 frame_count++;
6871 } else {
6872 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6873 if (pdest_frame->nFilledLen) {
6874 /*Push the frame to the Decoder*/
6875 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6876 return OMX_ErrorBadParameter;
6877 }
6878 frame_count++;
6879 pdest_frame = NULL;
6880
6881 if (m_input_free_q.m_size) {
6882 m_input_free_q.pop_entry(&address,&p2,&id);
6883 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6884 pdest_frame->nFilledLen = 0;
6885 }
6886 } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
6887 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
6888 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
6889 (unsigned)NULL);
6890 pdest_frame = NULL;
6891 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006892 }
Arun Menon906de572013-06-18 17:01:40 -07006893 } else {
6894 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
6895 /*Check if Destination Buffer is full*/
6896 if (pdest_frame->nAllocLen ==
6897 pdest_frame->nFilledLen + pdest_frame->nOffset) {
6898 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
6899 return OMX_ErrorStreamCorrupt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006900 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006901 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006902
Arun Menon906de572013-06-18 17:01:40 -07006903 if (psource_frame->nFilledLen == 0) {
6904 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6905 if (pdest_frame) {
6906 pdest_frame->nFlags |= psource_frame->nFlags;
6907 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
6908 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6909 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
6910 pdest_frame->nFilledLen,frame_count++);
6911 /*Push the frame to the Decoder*/
6912 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6913 return OMX_ErrorBadParameter;
6914 }
6915 frame_count++;
6916 pdest_frame = NULL;
6917 } else {
6918 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
6919 generate_ebd = OMX_FALSE;
6920 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006921 }
Arun Menon906de572013-06-18 17:01:40 -07006922 if (generate_ebd) {
6923 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
6924 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6925 psource_frame = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006926
Arun Menon906de572013-06-18 17:01:40 -07006927 if (m_input_pending_q.m_size) {
6928 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
6929 m_input_pending_q.pop_entry(&address,&p2,&id);
6930 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6931 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
6932 psource_frame->nTimeStamp);
6933 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
6934 psource_frame->nFlags,psource_frame->nFilledLen);
6935 }
6936 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006937 }
Arun Menon906de572013-06-18 17:01:40 -07006938 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006939}
6940
6941OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
6942{
Arun Menon906de572013-06-18 17:01:40 -07006943 OMX_U32 partial_frame = 1;
6944 unsigned address = 0, p2 = 0, id = 0;
6945 OMX_BOOL isNewFrame = OMX_FALSE;
6946 OMX_BOOL generate_ebd = OMX_TRUE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006947
Arun Menon906de572013-06-18 17:01:40 -07006948 if (h264_scratch.pBuffer == NULL) {
6949 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
6950 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006951 }
Arun Menon906de572013-06-18 17:01:40 -07006952 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
6953 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
6954 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
6955 if (h264_scratch.nFilledLen && look_ahead_nal) {
6956 look_ahead_nal = false;
6957 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6958 h264_scratch.nFilledLen) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07006959 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6960 h264_scratch.pBuffer,h264_scratch.nFilledLen);
6961 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
Arun Menon906de572013-06-18 17:01:40 -07006962 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006963 h264_scratch.nFilledLen = 0;
Arun Menon906de572013-06-18 17:01:40 -07006964 } else {
6965 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006966 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006967 }
Arun Menon906de572013-06-18 17:01:40 -07006968 }
Praveen Chavance0b5e82013-08-08 05:23:34 -07006969
6970 /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
6971 in EOS flag getting associated with the destination
6972 */
6973 if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
6974 pdest_frame->nFilledLen) {
6975 DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
6976 generate_ebd = OMX_FALSE;
6977 }
6978
Arun Menon906de572013-06-18 17:01:40 -07006979 if (nal_length == 0) {
6980 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
6981 if (m_frame_parser.parse_sc_frame(psource_frame,
6982 &h264_scratch,&partial_frame) == -1) {
6983 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
Shalaj Jain273b3e02012-06-22 19:08:03 -07006984 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006985 }
Arun Menon906de572013-06-18 17:01:40 -07006986 } else {
6987 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
6988 if (m_frame_parser.parse_h264_nallength(psource_frame,
6989 &h264_scratch,&partial_frame) == -1) {
6990 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
6991 return OMX_ErrorBadParameter;
6992 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006993 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006994
Arun Menon906de572013-06-18 17:01:40 -07006995 if (partial_frame == 0) {
6996 if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
6997 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
6998 nal_count++;
6999 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7000 h264_scratch.nFlags = psource_frame->nFlags;
7001 } else {
7002 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
7003 if (h264_scratch.nFilledLen) {
7004 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7005 NALU_TYPE_SPS);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007006#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
Arun Menon906de572013-06-18 17:01:40 -07007007 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7008 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7009 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7010 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7011 // If timeinfo is present frame info from SEI is already processed
7012 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7013 h264_scratch.nFilledLen, NALU_TYPE_SEI);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007014#endif
Arun Menon906de572013-06-18 17:01:40 -07007015 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7016 nal_count++;
7017 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7018 pdest_frame->nTimeStamp = h264_last_au_ts;
7019 pdest_frame->nFlags = h264_last_au_flags;
7020#ifdef PANSCAN_HDLR
7021 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7022 h264_parser->update_panscan_data(h264_last_au_ts);
7023#endif
7024 }
7025 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7026 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7027 h264_last_au_ts = h264_scratch.nTimeStamp;
7028 h264_last_au_flags = h264_scratch.nFlags;
7029#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7030 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7031 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7032 if (!VALID_TS(h264_last_au_ts))
7033 h264_last_au_ts = ts_in_sei;
7034 }
7035#endif
7036 } else
7037 h264_last_au_ts = LLONG_MAX;
7038 }
7039
7040 if (!isNewFrame) {
7041 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7042 h264_scratch.nFilledLen) {
7043 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
7044 h264_scratch.nFilledLen);
7045 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7046 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7047 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7048 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7049 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7050 h264_scratch.nFilledLen = 0;
7051 } else {
7052 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7053 return OMX_ErrorBadParameter;
7054 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007055 } else if(h264_scratch.nFilledLen) {
Arun Menon906de572013-06-18 17:01:40 -07007056 look_ahead_nal = true;
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05307057 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007058 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7059 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
7060 pdest_frame->nFilledLen,frame_count++);
7061
7062 if (pdest_frame->nFilledLen == 0) {
7063 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7064 look_ahead_nal = false;
7065 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7066 h264_scratch.nFilledLen) {
7067 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7068 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7069 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7070 h264_scratch.nFilledLen = 0;
7071 } else {
7072 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7073 return OMX_ErrorBadParameter;
7074 }
7075 } else {
7076 if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
7077 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7078 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7079 }
7080 /*Push the frame to the Decoder*/
7081 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7082 return OMX_ErrorBadParameter;
7083 }
7084 //frame_count++;
7085 pdest_frame = NULL;
7086 if (m_input_free_q.m_size) {
7087 m_input_free_q.pop_entry(&address,&p2,&id);
7088 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7089 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7090 pdest_frame->nFilledLen = 0;
7091 pdest_frame->nFlags = 0;
7092 pdest_frame->nTimeStamp = LLONG_MAX;
7093 }
7094 }
7095 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007096 }
Arun Menon906de572013-06-18 17:01:40 -07007097 } else {
7098 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
7099 /*Check if Destination Buffer is full*/
7100 if (h264_scratch.nAllocLen ==
7101 h264_scratch.nFilledLen + h264_scratch.nOffset) {
7102 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7103 return OMX_ErrorStreamCorrupt;
7104 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007105 }
Arun Menon906de572013-06-18 17:01:40 -07007106
7107 if (!psource_frame->nFilledLen) {
7108 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7109
7110 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7111 if (pdest_frame) {
7112 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7113 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7114 h264_scratch.nFilledLen) {
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007115 if(pdest_frame->nFilledLen == 0) {
7116 /* No residual frame from before, send whatever
7117 * we have left */
7118 memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7119 h264_scratch.pBuffer, h264_scratch.nFilledLen);
7120 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7121 h264_scratch.nFilledLen = 0;
7122 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7123 } else {
7124 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7125 if(!isNewFrame) {
7126 /* Have a residual frame, but we know that the
7127 * AU in this frame is belonging to whatever
7128 * frame we had left over. So append it */
7129 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7130 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7131 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7132 h264_scratch.nFilledLen = 0;
7133 pdest_frame->nTimeStamp = h264_last_au_ts;
7134 } else {
7135 /* Completely new frame, let's just push what
7136 * we have now. The resulting EBD would trigger
7137 * another push */
7138 generate_ebd = OMX_FALSE;
7139 pdest_frame->nTimeStamp = h264_last_au_ts;
7140 h264_last_au_ts = h264_scratch.nTimeStamp;
7141 }
7142 }
Arun Menon906de572013-06-18 17:01:40 -07007143 } else {
7144 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7145 return OMX_ErrorBadParameter;
7146 }
Leena Winterrowd5a974ce2013-08-06 15:10:36 -07007147
7148 /* Iff we coalesced two buffers, inherit the flags of both bufs */
7149 if(generate_ebd == OMX_TRUE) {
7150 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7151 }
Arun Menon906de572013-06-18 17:01:40 -07007152
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05307153 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llu",
Arun Menon906de572013-06-18 17:01:40 -07007154 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7155 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7156#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7157 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7158 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7159 if (!VALID_TS(pdest_frame->nTimeStamp))
7160 pdest_frame->nTimeStamp = ts_in_sei;
7161 }
7162#endif
7163 /*Push the frame to the Decoder*/
7164 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7165 return OMX_ErrorBadParameter;
7166 }
7167 frame_count++;
7168 pdest_frame = NULL;
7169 } else {
7170 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
7171 pdest_frame,h264_scratch.nFilledLen);
7172 generate_ebd = OMX_FALSE;
7173 }
7174 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007175 }
Arun Menon906de572013-06-18 17:01:40 -07007176 if (generate_ebd && !psource_frame->nFilledLen) {
7177 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7178 psource_frame = NULL;
7179 if (m_input_pending_q.m_size) {
7180 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7181 m_input_pending_q.pop_entry(&address,&p2,&id);
7182 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7183 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
7184 psource_frame->nFlags,psource_frame->nFilledLen);
7185 }
7186 }
7187 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007188}
7189
7190OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7191{
7192 OMX_U8 *buf, *pdest;
7193 OMX_U32 partial_frame = 1;
7194 OMX_U32 buf_len, dest_len;
7195
Arun Menon906de572013-06-18 17:01:40 -07007196 if (first_frame == 0) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007197 first_frame = 1;
7198 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
Arun Menon906de572013-06-18 17:01:40 -07007199 if (!m_vendor_config.pData) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007200 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7201 buf = psource_frame->pBuffer;
7202 buf_len = psource_frame->nFilledLen;
7203
7204 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
Arun Menon906de572013-06-18 17:01:40 -07007205 VC1_SP_MP_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007206 m_vc1_profile = VC1_SP_MP_RCV;
Arun Menon906de572013-06-18 17:01:40 -07007207 } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007208 m_vc1_profile = VC1_AP;
Arun Menon906de572013-06-18 17:01:40 -07007209 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007210 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7211 return OMX_ErrorStreamCorrupt;
7212 }
Arun Menon906de572013-06-18 17:01:40 -07007213 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007214 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7215 pdest_frame->nOffset;
7216 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
Arun Menon906de572013-06-18 17:01:40 -07007217 pdest_frame->nOffset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007218
Arun Menon906de572013-06-18 17:01:40 -07007219 if (dest_len < m_vendor_config.nDataSize) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007220 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7221 return OMX_ErrorBadParameter;
Arun Menon906de572013-06-18 17:01:40 -07007222 } else {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007223 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7224 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7225 }
7226 }
7227 }
7228
Arun Menon906de572013-06-18 17:01:40 -07007229 switch (m_vc1_profile) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007230 case VC1_AP:
7231 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
Arun Menon906de572013-06-18 17:01:40 -07007232 if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07007233 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7234 return OMX_ErrorBadParameter;
7235 }
Arun Menon906de572013-06-18 17:01:40 -07007236 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007237
7238 case VC1_SP_MP_RCV:
7239 default:
7240 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7241 return OMX_ErrorBadParameter;
7242 }
7243 return OMX_ErrorNone;
7244}
7245
David Ng38e2d232013-03-15 20:05:58 -07007246#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007247bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007248 OMX_U32 alignment)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007249{
Arun Menon906de572013-06-18 17:01:40 -07007250 struct pmem_allocation allocation;
7251 allocation.size = buffer_size;
7252 allocation.align = clip2(alignment);
7253 if (allocation.align < 4096) {
7254 allocation.align = 4096;
7255 }
7256 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
7257 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7258 allocation.align, allocation.size);
7259 return false;
7260 }
7261 return true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007262}
David Ng38e2d232013-03-15 20:05:58 -07007263#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007264#ifdef USE_ION
7265int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
Arun Menon906de572013-06-18 17:01:40 -07007266 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7267 struct ion_fd_data *fd_data, int flag)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007268{
Arun Menon906de572013-06-18 17:01:40 -07007269 int fd = -EINVAL;
7270 int rc = -EINVAL;
7271 int ion_dev_flag;
7272 struct vdec_ion ion_buf_info;
7273 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7274 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7275 return -EINVAL;
7276 }
7277 ion_dev_flag = O_RDONLY;
7278 fd = open (MEM_DEVICE, ion_dev_flag);
7279 if (fd < 0) {
7280 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7281 return fd;
7282 }
7283 alloc_data->flags = 0;
7284 if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7285 alloc_data->flags |= ION_FLAG_CACHED;
7286 }
7287 alloc_data->len = buffer_size;
7288 alloc_data->align = clip2(alignment);
7289 if (alloc_data->align < 4096) {
7290 alloc_data->align = 4096;
7291 }
7292 if ((secure_mode) && (flag & ION_SECURE))
7293 alloc_data->flags |= ION_SECURE;
Vinay Kalia53fa6832012-10-11 17:55:30 -07007294
Arun Menon906de572013-06-18 17:01:40 -07007295 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7296 if (secure_mode)
7297 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7298 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7299 if (rc || !alloc_data->handle) {
7300 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7301 alloc_data->handle = NULL;
7302 close(fd);
7303 fd = -ENOMEM;
7304 return fd;
7305 }
7306 fd_data->handle = alloc_data->handle;
7307 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7308 if (rc) {
7309 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7310 ion_buf_info.ion_alloc_data = *alloc_data;
7311 ion_buf_info.ion_device_fd = fd;
7312 ion_buf_info.fd_ion_data = *fd_data;
7313 free_ion_memory(&ion_buf_info);
7314 fd_data->fd =-1;
7315 close(fd);
7316 fd = -ENOMEM;
7317 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007318
Arun Menon906de572013-06-18 17:01:40 -07007319 return fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007320}
7321
Arun Menon906de572013-06-18 17:01:40 -07007322void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7323{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007324
Arun Menon906de572013-06-18 17:01:40 -07007325 if (!buf_ion_info) {
7326 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7327 return;
7328 }
7329 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7330 &buf_ion_info->ion_alloc_data.handle)) {
7331 DEBUG_PRINT_ERROR("\n ION: free failed" );
7332 }
7333 close(buf_ion_info->ion_device_fd);
7334 buf_ion_info->ion_device_fd = -1;
7335 buf_ion_info->ion_alloc_data.handle = NULL;
7336 buf_ion_info->fd_ion_data.fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007337}
7338#endif
7339void omx_vdec::free_output_buffer_header()
7340{
Arun Menon906de572013-06-18 17:01:40 -07007341 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7342 output_use_buffer = false;
7343 ouput_egl_buffers = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007344
Arun Menon906de572013-06-18 17:01:40 -07007345 if (m_out_mem_ptr) {
7346 free (m_out_mem_ptr);
7347 m_out_mem_ptr = NULL;
7348 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007349
Arun Menon906de572013-06-18 17:01:40 -07007350 if (m_platform_list) {
7351 free(m_platform_list);
7352 m_platform_list = NULL;
7353 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007354
Arun Menon906de572013-06-18 17:01:40 -07007355 if (drv_ctx.ptr_respbuffer) {
7356 free (drv_ctx.ptr_respbuffer);
7357 drv_ctx.ptr_respbuffer = NULL;
7358 }
7359 if (drv_ctx.ptr_outputbuffer) {
7360 free (drv_ctx.ptr_outputbuffer);
7361 drv_ctx.ptr_outputbuffer = NULL;
7362 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007363#ifdef USE_ION
7364 if (drv_ctx.op_buf_ion_info) {
7365 DEBUG_PRINT_LOW("\n Free o/p ion context");
Arun Menon906de572013-06-18 17:01:40 -07007366 free(drv_ctx.op_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007367 drv_ctx.op_buf_ion_info = NULL;
7368 }
7369#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007370#ifdef META_DATA_MODE_SUPPORTED
7371 if (out_dynamic_list) {
7372 free(out_dynamic_list);
7373 out_dynamic_list = NULL;
7374 }
7375#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007376}
7377
7378void omx_vdec::free_input_buffer_header()
7379{
7380 input_use_buffer = false;
Arun Menon906de572013-06-18 17:01:40 -07007381 if (arbitrary_bytes) {
Arun Menon906de572013-06-18 17:01:40 -07007382 if (m_inp_heap_ptr) {
7383 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7384 free (m_inp_heap_ptr);
7385 m_inp_heap_ptr = NULL;
7386 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007387
Arun Menon906de572013-06-18 17:01:40 -07007388 if (m_phdr_pmem_ptr) {
7389 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7390 free (m_phdr_pmem_ptr);
7391 m_phdr_pmem_ptr = NULL;
7392 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007393 }
Arun Menon906de572013-06-18 17:01:40 -07007394 if (m_inp_mem_ptr) {
7395 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7396 free (m_inp_mem_ptr);
7397 m_inp_mem_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007398 }
Leena Winterrowd1d2424a2013-08-20 15:26:02 -07007399 /* We just freed all the buffer headers, every thing in m_input_free_q
7400 * is now invalid */
7401 while (m_input_free_q.m_size) {
7402 unsigned address, p2, id;
7403 m_input_free_q.pop_entry(&address, &p2, &id);
7404 }
Arun Menon906de572013-06-18 17:01:40 -07007405 if (drv_ctx.ptr_inputbuffer) {
7406 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7407 free (drv_ctx.ptr_inputbuffer);
7408 drv_ctx.ptr_inputbuffer = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007409 }
7410#ifdef USE_ION
7411 if (drv_ctx.ip_buf_ion_info) {
7412 DEBUG_PRINT_LOW("\n Free ion context");
Arun Menon906de572013-06-18 17:01:40 -07007413 free(drv_ctx.ip_buf_ion_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007414 drv_ctx.ip_buf_ion_info = NULL;
7415 }
7416#endif
7417}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007418
7419int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007420{
Arun Menon906de572013-06-18 17:01:40 -07007421 enum v4l2_buf_type btype;
7422 int rc = 0;
7423 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007424
Arun Menon906de572013-06-18 17:01:40 -07007425 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7426 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7427 v4l2_port = OUTPUT_PORT;
7428 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7429 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7430 v4l2_port = CAPTURE_PORT;
7431 } else if (port == OMX_ALL) {
7432 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7433 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007434
Arun Menon906de572013-06-18 17:01:40 -07007435 if (!rc_input)
7436 return rc_input;
7437 else
7438 return rc_output;
7439 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007440
Arun Menon906de572013-06-18 17:01:40 -07007441 if (!streaming[v4l2_port]) {
7442 // already streamed off, warn and move on
7443 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7444 " which is already streamed off", v4l2_port);
7445 return 0;
7446 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007447
Arun Menon906de572013-06-18 17:01:40 -07007448 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007449
Arun Menon906de572013-06-18 17:01:40 -07007450 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7451 if (rc) {
7452 /*TODO: How to handle this case */
7453 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
7454 } else {
7455 streaming[v4l2_port] = false;
7456 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007457
Arun Menon906de572013-06-18 17:01:40 -07007458 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007459}
7460
7461OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7462{
Arun Menon906de572013-06-18 17:01:40 -07007463 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7464 struct v4l2_requestbuffers bufreq;
7465 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
7466 struct v4l2_format fmt;
7467 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007468 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
Arun Menon906de572013-06-18 17:01:40 -07007469 buffer_prop->actualcount, buffer_prop->buffer_size);
7470 bufreq.memory = V4L2_MEMORY_USERPTR;
7471 bufreq.count = 1;
7472 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7473 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7474 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7475 fmt.fmt.pix_mp.pixelformat = output_capability;
7476 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7477 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7478 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7479 fmt.fmt.pix_mp.pixelformat = capture_capability;
7480 } else {
7481 eRet = OMX_ErrorBadParameter;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007482 }
Arun Menon906de572013-06-18 17:01:40 -07007483 if (eRet==OMX_ErrorNone) {
7484 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007485 }
Arun Menon906de572013-06-18 17:01:40 -07007486 if (ret) {
7487 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7488 /*TODO: How to handle this case */
7489 eRet = OMX_ErrorInsufficientResources;
7490 return eRet;
7491 } else {
7492 buffer_prop->actualcount = bufreq.count;
7493 buffer_prop->mincount = bufreq.count;
7494 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007495 }
Arun Menon906de572013-06-18 17:01:40 -07007496 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7497 buffer_prop->actualcount, buffer_prop->buffer_size);
7498
7499 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7500 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7501
7502 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7503
7504 update_resolution(fmt.fmt.pix_mp.width,
7505 fmt.fmt.pix_mp.height,
7506 fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
7507 fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
7508 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7509 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
7510 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
7511
7512 if (ret) {
7513 /*TODO: How to handle this case */
7514 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7515 eRet = OMX_ErrorInsufficientResources;
7516 } else {
7517 int extra_idx = 0;
7518
7519 eRet = is_video_session_supported();
7520 if (eRet)
7521 return eRet;
7522
7523 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7524 buf_size = buffer_prop->buffer_size;
7525 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7526 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7527 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7528 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7529 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7530 return OMX_ErrorBadParameter;
7531 }
7532 if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7533 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7534 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7535 }
7536 if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7537 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7538 }
7539 if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7540 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7541 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7542 client_extra_data_size);
7543 }
7544 if (client_extra_data_size) {
7545 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7546 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7547 }
7548 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7549 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7550 drv_ctx.extradata_info.buffer_size = extra_data_size;
7551 buf_size += client_extra_data_size;
7552 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7553 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7554 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7555 if (in_reconfig) // BufReq will be set to driver when port is disabled
7556 buffer_prop->buffer_size = buf_size;
7557 else if (buf_size != buffer_prop->buffer_size) {
7558 buffer_prop->buffer_size = buf_size;
7559 eRet = set_buffer_req(buffer_prop);
7560 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007561 }
Arun Menon906de572013-06-18 17:01:40 -07007562 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7563 buffer_prop->actualcount, buffer_prop->buffer_size);
7564 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007565}
7566
7567OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7568{
Arun Menon906de572013-06-18 17:01:40 -07007569 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7570 unsigned buf_size = 0;
7571 struct v4l2_format fmt;
7572 struct v4l2_requestbuffers bufreq;
7573 int ret;
7574 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7575 buffer_prop->actualcount, buffer_prop->buffer_size);
7576 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7577 if (buf_size != buffer_prop->buffer_size) {
7578 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7579 buffer_prop->buffer_size, buf_size);
7580 eRet = OMX_ErrorBadParameter;
7581 } else {
7582 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7583 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007584
Arun Menon906de572013-06-18 17:01:40 -07007585 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7586 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7587 fmt.fmt.pix_mp.pixelformat = output_capability;
7588 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7589 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7590 fmt.fmt.pix_mp.pixelformat = capture_capability;
7591 } else {
7592 eRet = OMX_ErrorBadParameter;
7593 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007594
Arun Menon906de572013-06-18 17:01:40 -07007595 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7596 if (ret) {
7597 /*TODO: How to handle this case */
7598 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
7599 eRet = OMX_ErrorInsufficientResources;
7600 }
7601
7602 bufreq.memory = V4L2_MEMORY_USERPTR;
7603 bufreq.count = buffer_prop->actualcount;
7604 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7605 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7606 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7607 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7608 } else {
7609 eRet = OMX_ErrorBadParameter;
7610 }
7611
7612 if (eRet==OMX_ErrorNone) {
7613 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7614 }
7615
7616 if (ret) {
7617 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7618 /*TODO: How to handle this case */
7619 eRet = OMX_ErrorInsufficientResources;
7620 } else if (bufreq.count < buffer_prop->actualcount) {
7621 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7622 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7623 buffer_prop->actualcount, bufreq.count);
7624 eRet = OMX_ErrorInsufficientResources;
7625 } else {
7626 if (!client_buffers.update_buffer_req()) {
7627 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7628 eRet = OMX_ErrorInsufficientResources;
7629 }
7630 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007631 }
Arun Menon906de572013-06-18 17:01:40 -07007632 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007633}
7634
Shalaj Jain273b3e02012-06-22 19:08:03 -07007635OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7636{
Arun Menon906de572013-06-18 17:01:40 -07007637 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7638 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007639}
7640
7641OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7642{
Arun Menon906de572013-06-18 17:01:40 -07007643 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7644 if (!portDefn) {
7645 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007646 }
Arun Menon906de572013-06-18 17:01:40 -07007647 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
7648 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7649 portDefn->nSize = sizeof(portDefn);
7650 portDefn->eDomain = OMX_PortDomainVideo;
7651 if (drv_ctx.frame_rate.fps_denominator > 0)
7652 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7653 drv_ctx.frame_rate.fps_denominator;
7654 else {
7655 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7656 return OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007657 }
Arun Menon906de572013-06-18 17:01:40 -07007658 if (0 == portDefn->nPortIndex) {
7659 portDefn->eDir = OMX_DirInput;
7660 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7661 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
7662 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
7663 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7664 portDefn->format.video.eCompressionFormat = eCompressionFormat;
7665 portDefn->bEnabled = m_inp_bEnabled;
7666 portDefn->bPopulated = m_inp_bPopulated;
7667 } else if (1 == portDefn->nPortIndex) {
7668 unsigned int buf_size = 0;
7669 if (!client_buffers.update_buffer_req()) {
7670 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
7671 return OMX_ErrorHardware;
7672 }
7673 if (!client_buffers.get_buffer_req(buf_size)) {
7674 DEBUG_PRINT_ERROR("\n update buffer requirements");
7675 return OMX_ErrorHardware;
7676 }
7677 portDefn->nBufferSize = buf_size;
7678 portDefn->eDir = OMX_DirOutput;
7679 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7680 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
7681 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7682 portDefn->bEnabled = m_out_bEnabled;
7683 portDefn->bPopulated = m_out_bPopulated;
7684 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
7685 DEBUG_PRINT_ERROR("\n Error in getting color format");
7686 return OMX_ErrorHardware;
7687 }
7688 } else {
7689 portDefn->eDir = OMX_DirMax;
7690 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7691 (int)portDefn->nPortIndex);
7692 eRet = OMX_ErrorBadPortIndex;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007693 }
Arun Menon906de572013-06-18 17:01:40 -07007694 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
7695 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
7696 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7697 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7698 DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
7699 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
7700 portDefn->format.video.nFrameHeight,
7701 portDefn->format.video.nStride,
7702 portDefn->format.video.nSliceHeight);
7703 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007704
7705}
7706
7707OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7708{
Arun Menon906de572013-06-18 17:01:40 -07007709 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7710 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7711 unsigned i= 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007712
Arun Menon906de572013-06-18 17:01:40 -07007713 if (!m_out_mem_ptr) {
7714 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
7715 int nBufHdrSize = 0;
7716 int nPlatformEntrySize = 0;
7717 int nPlatformListSize = 0;
7718 int nPMEMInfoSize = 0;
7719 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
7720 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
7721 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007722
Arun Menon906de572013-06-18 17:01:40 -07007723 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
7724 drv_ctx.op_buf.actualcount);
7725 nBufHdrSize = drv_ctx.op_buf.actualcount *
7726 sizeof(OMX_BUFFERHEADERTYPE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007727
Arun Menon906de572013-06-18 17:01:40 -07007728 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
7729 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7730 nPlatformListSize = drv_ctx.op_buf.actualcount *
7731 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7732 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7733 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007734
Arun Menon906de572013-06-18 17:01:40 -07007735 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
7736 sizeof(OMX_BUFFERHEADERTYPE),
7737 nPMEMInfoSize,
7738 nPlatformListSize);
7739 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
7740 m_out_bm_count);
7741 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
7742 // Alloc mem for platform specific info
7743 char *pPtr=NULL;
7744 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7745 nPMEMInfoSize,1);
7746 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7747 calloc (sizeof(struct vdec_bufferpayload),
7748 drv_ctx.op_buf.actualcount);
7749 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
7750 calloc (sizeof (struct vdec_output_frameinfo),
7751 drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007752#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007753 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7754 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007755#endif
Arun Menonbdb80b02013-08-12 17:45:54 -07007756#ifdef META_DATA_MODE_SUPPORTED
7757 if (dynamic_buf_mode) {
7758 out_dynamic_list = (struct dynamic_buf_list *) \
7759 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
7760 }
7761#endif
Arun Menon906de572013-06-18 17:01:40 -07007762 if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7763 && drv_ctx.ptr_respbuffer) {
7764 bufHdr = m_out_mem_ptr;
7765 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7766 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7767 (((char *) m_platform_list) + nPlatformListSize);
7768 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7769 (((char *) m_platform_entry) + nPlatformEntrySize);
7770 pPlatformList = m_platform_list;
7771 pPlatformEntry = m_platform_entry;
7772 pPMEMInfo = m_pmem_info;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007773
Arun Menon906de572013-06-18 17:01:40 -07007774 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007775
Arun Menon906de572013-06-18 17:01:40 -07007776 // Settting the entire storage nicely
7777 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
7778 m_out_mem_ptr,pPlatformEntry);
7779 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
7780 for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7781 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
7782 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
7783 // Set the values when we determine the right HxW param
7784 bufHdr->nAllocLen = 0;
7785 bufHdr->nFilledLen = 0;
7786 bufHdr->pAppPrivate = NULL;
7787 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
7788 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7789 pPlatformEntry->entry = pPMEMInfo;
7790 // Initialize the Platform List
7791 pPlatformList->nEntries = 1;
7792 pPlatformList->entryList = pPlatformEntry;
7793 // Keep pBuffer NULL till vdec is opened
7794 bufHdr->pBuffer = NULL;
7795 pPMEMInfo->offset = 0;
7796 pPMEMInfo->pmem_fd = 0;
7797 bufHdr->pPlatformPrivate = pPlatformList;
7798 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007799#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007800 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007801#endif
Arun Menon906de572013-06-18 17:01:40 -07007802 /*Create a mapping between buffers*/
7803 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7804 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7805 &drv_ctx.ptr_outputbuffer[i];
7806 // Move the buffer and buffer header pointers
7807 bufHdr++;
7808 pPMEMInfo++;
7809 pPlatformEntry++;
7810 pPlatformList++;
7811 }
7812 } else {
7813 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
7814 m_out_mem_ptr, pPtr);
7815 if (m_out_mem_ptr) {
7816 free(m_out_mem_ptr);
7817 m_out_mem_ptr = NULL;
7818 }
7819 if (pPtr) {
7820 free(pPtr);
7821 pPtr = NULL;
7822 }
7823 if (drv_ctx.ptr_outputbuffer) {
7824 free(drv_ctx.ptr_outputbuffer);
7825 drv_ctx.ptr_outputbuffer = NULL;
7826 }
7827 if (drv_ctx.ptr_respbuffer) {
7828 free(drv_ctx.ptr_respbuffer);
7829 drv_ctx.ptr_respbuffer = NULL;
7830 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007831#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07007832 if (drv_ctx.op_buf_ion_info) {
7833 DEBUG_PRINT_LOW("\n Free o/p ion context");
7834 free(drv_ctx.op_buf_ion_info);
7835 drv_ctx.op_buf_ion_info = NULL;
7836 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007837#endif
Arun Menon906de572013-06-18 17:01:40 -07007838 eRet = OMX_ErrorInsufficientResources;
7839 }
7840 } else {
7841 eRet = OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007842 }
Arun Menon906de572013-06-18 17:01:40 -07007843 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007844}
7845
7846void omx_vdec::complete_pending_buffer_done_cbs()
7847{
Arun Menon906de572013-06-18 17:01:40 -07007848 unsigned p1;
7849 unsigned p2;
7850 unsigned ident;
7851 omx_cmd_queue tmp_q, pending_bd_q;
7852 pthread_mutex_lock(&m_lock);
7853 // pop all pending GENERATE FDB from ftb queue
7854 while (m_ftb_q.m_size) {
7855 m_ftb_q.pop_entry(&p1,&p2,&ident);
7856 if (ident == OMX_COMPONENT_GENERATE_FBD) {
7857 pending_bd_q.insert_entry(p1,p2,ident);
7858 } else {
7859 tmp_q.insert_entry(p1,p2,ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007860 }
Arun Menon906de572013-06-18 17:01:40 -07007861 }
7862 //return all non GENERATE FDB to ftb queue
7863 while (tmp_q.m_size) {
7864 tmp_q.pop_entry(&p1,&p2,&ident);
7865 m_ftb_q.insert_entry(p1,p2,ident);
7866 }
7867 // pop all pending GENERATE EDB from etb queue
7868 while (m_etb_q.m_size) {
7869 m_etb_q.pop_entry(&p1,&p2,&ident);
7870 if (ident == OMX_COMPONENT_GENERATE_EBD) {
7871 pending_bd_q.insert_entry(p1,p2,ident);
7872 } else {
7873 tmp_q.insert_entry(p1,p2,ident);
7874 }
7875 }
7876 //return all non GENERATE FDB to etb queue
7877 while (tmp_q.m_size) {
7878 tmp_q.pop_entry(&p1,&p2,&ident);
7879 m_etb_q.insert_entry(p1,p2,ident);
7880 }
7881 pthread_mutex_unlock(&m_lock);
7882 // process all pending buffer dones
7883 while (pending_bd_q.m_size) {
7884 pending_bd_q.pop_entry(&p1,&p2,&ident);
7885 switch (ident) {
7886 case OMX_COMPONENT_GENERATE_EBD:
7887 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
7888 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
7889 omx_report_error ();
7890 }
7891 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007892
Arun Menon906de572013-06-18 17:01:40 -07007893 case OMX_COMPONENT_GENERATE_FBD:
7894 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
7895 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
7896 omx_report_error ();
7897 }
7898 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007899 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007900 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007901}
7902
7903void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
7904{
Arun Menon906de572013-06-18 17:01:40 -07007905 OMX_U32 new_frame_interval = 0;
7906 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
7907 && llabs(act_timestamp - prev_ts) > 2000) {
7908 new_frame_interval = client_set_fps ? frm_int :
7909 llabs(act_timestamp - prev_ts);
7910 if (new_frame_interval < frm_int || frm_int == 0) {
7911 frm_int = new_frame_interval;
7912 if (frm_int) {
7913 drv_ctx.frame_rate.fps_numerator = 1e6;
7914 drv_ctx.frame_rate.fps_denominator = frm_int;
7915 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
7916 frm_int, drv_ctx.frame_rate.fps_numerator /
7917 (float)drv_ctx.frame_rate.fps_denominator);
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007918
Arun Menon906de572013-06-18 17:01:40 -07007919 /* We need to report the difference between this FBD and the previous FBD
7920 * back to the driver for clock scaling purposes. */
7921 struct v4l2_outputparm oparm;
7922 /*XXX: we're providing timing info as seconds per frame rather than frames
7923 * per second.*/
7924 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
7925 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007926
Arun Menon906de572013-06-18 17:01:40 -07007927 struct v4l2_streamparm sparm;
7928 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7929 sparm.parm.output = oparm;
7930 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
7931 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
7932 performance might be affected");
7933 }
7934
7935 }
Deva Ramasubramaniane47e05b2013-04-24 15:23:29 -07007936 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007937 }
Arun Menon906de572013-06-18 17:01:40 -07007938 prev_ts = act_timestamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007939}
7940
7941void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
7942{
Arun Menon906de572013-06-18 17:01:40 -07007943 if (rst_prev_ts && VALID_TS(act_timestamp)) {
7944 prev_ts = act_timestamp;
7945 rst_prev_ts = false;
7946 } else if (VALID_TS(prev_ts)) {
7947 bool codec_cond = (drv_ctx.timestamp_adjust)?
7948 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
7949 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
7950 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
7951 if (frm_int > 0 && codec_cond) {
7952 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
7953 act_timestamp = prev_ts + frm_int;
7954 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
7955 prev_ts = act_timestamp;
7956 } else
7957 set_frame_rate(act_timestamp);
7958 } else if (frm_int > 0) // In this case the frame rate was set along
7959 { // with the port definition, start ts with 0
7960 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
7961 rst_prev_ts = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007962 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007963}
7964
7965void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
7966{
Arun Menon906de572013-06-18 17:01:40 -07007967 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
7968 OMX_U32 num_conceal_MB = 0;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05307969 OMX_TICKS time_stamp = 0;
Arun Menon906de572013-06-18 17:01:40 -07007970 OMX_U32 frame_rate = 0;
7971 int consumed_len = 0;
7972 OMX_U32 num_MB_in_frame;
7973 OMX_U32 recovery_sei_flags = 1;
7974 int enable = 0;
7975 OMX_U32 mbaff = 0;
7976 int buf_index = p_buf_hdr - m_out_mem_ptr;
7977 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
7978 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
7979 p_buf_hdr->nOffset;
7980 if (!drv_ctx.extradata_info.uaddr) {
7981 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007982 }
Arun Menon906de572013-06-18 17:01:40 -07007983 p_extra = (OMX_OTHER_EXTRADATATYPE *)
7984 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
7985 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
7986 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
7987 p_extra = NULL;
7988 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
7989 if (data) {
7990 while ((consumed_len < drv_ctx.extradata_info.buffer_size)
7991 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
7992 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
7993 DEBUG_PRINT_LOW("Invalid extra data size");
7994 break;
7995 }
7996 switch ((unsigned long)data->eType) {
7997 case EXTRADATA_INTERLACE_VIDEO:
7998 struct msm_vidc_interlace_payload *payload;
7999 payload = (struct msm_vidc_interlace_payload *)data->data;
8000 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8001 if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8002 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8003 else {
8004 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8005 enable = 1;
8006 }
8007 if (m_enable_android_native_buffers)
8008 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
8009 PP_PARAM_INTERLACED, (void*)&enable);
8010 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8011 append_interlace_extradata(p_extra, payload->format);
8012 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8013 }
8014 break;
8015 case EXTRADATA_FRAME_RATE:
8016 struct msm_vidc_framerate_payload *frame_rate_payload;
8017 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8018 frame_rate = frame_rate_payload->frame_rate;
8019 break;
8020 case EXTRADATA_TIMESTAMP:
8021 struct msm_vidc_ts_payload *time_stamp_payload;
8022 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308023 time_stamp = time_stamp_payload->timestamp_lo;
8024 time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
8025 p_buf_hdr->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008026 break;
8027 case EXTRADATA_NUM_CONCEALED_MB:
8028 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8029 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8030 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8031 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8032 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8033 break;
8034 case EXTRADATA_INDEX:
8035 int *etype;
8036 etype = (int *)(data->data);
8037 if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
8038 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8039 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
8040 if (aspect_ratio_payload) {
8041 ((struct vdec_output_frameinfo *)
8042 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8043 ((struct vdec_output_frameinfo *)
8044 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8045 }
8046 }
8047 break;
8048 case EXTRADATA_RECOVERY_POINT_SEI:
8049 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8050 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8051 recovery_sei_flags = recovery_sei_payload->flags;
8052 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8053 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
8054 DEBUG_PRINT_HIGH("\n");
8055 DEBUG_PRINT_HIGH("***************************************************\n");
8056 DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
8057 DEBUG_PRINT_HIGH("***************************************************\n");
8058 }
8059 break;
8060 case EXTRADATA_PANSCAN_WINDOW:
8061 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8062 break;
8063 case EXTRADATA_MPEG2_SEQDISP:
8064 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
8065 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
8066 if (seqdisp_payload) {
8067 m_disp_hor_size = seqdisp_payload->disp_width;
8068 m_disp_vert_size = seqdisp_payload->disp_height;
8069 }
8070 break;
8071 default:
8072 goto unrecognized_extradata;
8073 }
8074 consumed_len += data->nSize;
8075 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
8076 }
8077 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8078 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8079 append_frame_info_extradata(p_extra,
8080 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308081 time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
Arun Menon906de572013-06-18 17:01:40 -07008082 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
8083 }
8084 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008085unrecognized_extradata:
Arun Menon906de572013-06-18 17:01:40 -07008086 if (!secure_mode && client_extradata)
8087 append_terminator_extradata(p_extra);
8088 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008089}
8090
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008091OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
Arun Menon906de572013-06-18 17:01:40 -07008092 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008093{
Arun Menon906de572013-06-18 17:01:40 -07008094 OMX_ERRORTYPE ret = OMX_ErrorNone;
8095 struct v4l2_control control;
8096 if (m_state != OMX_StateLoaded) {
8097 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8098 return OMX_ErrorIncorrectStateOperation;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008099 }
Arun Menon906de572013-06-18 17:01:40 -07008100 DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
8101 client_extradata, requested_extradata, enable, is_internal);
8102
8103 if (!is_internal) {
8104 if (enable)
8105 client_extradata |= requested_extradata;
8106 else
8107 client_extradata = client_extradata & ~requested_extradata;
8108 }
8109
8110 if (enable) {
8111 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8112 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8113 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8114 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8115 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8116 " Quality of interlaced clips might be impacted.\n");
8117 }
8118 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
8119 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8120 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8121 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8122 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8123 }
8124 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8125 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8126 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8127 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8128 }
8129 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8130 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8131 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8132 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8133 }
8134 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8135 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8136 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8137 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8138 }
8139 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8140 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8141 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8142 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8143 }
8144 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8145 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8146 control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
8147 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8148 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8149 }
8150 }
8151 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
8152 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8153 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8154 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8155 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8156 }
8157 }
8158 }
8159 ret = get_buffer_req(&drv_ctx.op_buf);
8160 return ret;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008161}
8162
8163OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8164{
Arun Menon906de572013-06-18 17:01:40 -07008165 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8166 OMX_U8 *data_ptr = extra->data, data = 0;
8167 while (byte_count < extra->nDataSize) {
8168 data = *data_ptr;
8169 while (data) {
8170 num_MB += (data&0x01);
8171 data >>= 1;
8172 }
8173 data_ptr++;
8174 byte_count++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008175 }
Arun Menon906de572013-06-18 17:01:40 -07008176 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8177 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8178 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008179}
8180
8181void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8182{
Arun Menon906de572013-06-18 17:01:40 -07008183 if (!m_debug_extradata)
8184 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008185
8186 DEBUG_PRINT_HIGH(
Arun Menon906de572013-06-18 17:01:40 -07008187 "============== Extra Data ==============\n"
8188 " Size: %lu \n"
8189 " Version: %lu \n"
8190 " PortIndex: %lu \n"
8191 " Type: %x \n"
8192 " DataSize: %lu \n",
8193 extra->nSize, extra->nVersion.nVersion,
8194 extra->nPortIndex, extra->eType, extra->nDataSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008195
Arun Menon906de572013-06-18 17:01:40 -07008196 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
8197 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8198 DEBUG_PRINT_HIGH(
8199 "------ Interlace Format ------\n"
8200 " Size: %lu \n"
8201 " Version: %lu \n"
8202 " PortIndex: %lu \n"
8203 " Is Interlace Format: %d \n"
8204 " Interlace Formats: %lu \n"
8205 "=========== End of Interlace ===========\n",
8206 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8207 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8208 } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
8209 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8210
8211 DEBUG_PRINT_HIGH(
8212 "-------- Frame Format --------\n"
8213 " Picture Type: %d \n"
8214 " Interlace Type: %d \n"
8215 " Pan Scan Total Frame Num: %lu \n"
8216 " Concealed Macro Blocks: %lu \n"
8217 " frame rate: %lu \n"
Rajeshwar Kurapatya59a8ea2013-09-25 16:05:41 +05308218 " Time Stamp: %llu \n"
Arun Menon906de572013-06-18 17:01:40 -07008219 " Aspect Ratio X: %lu \n"
8220 " Aspect Ratio Y: %lu \n",
8221 fminfo->ePicType,
8222 fminfo->interlaceType,
8223 fminfo->panScan.numWindows,
8224 fminfo->nConcealedMacroblocks,
8225 fminfo->nFrameRate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308226 fminfo->nTimeStamp,
Arun Menon906de572013-06-18 17:01:40 -07008227 fminfo->aspectRatio.aspectRatioX,
8228 fminfo->aspectRatio.aspectRatioY);
8229
8230 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
8231 DEBUG_PRINT_HIGH(
8232 "------------------------------\n"
8233 " Pan Scan Frame Num: %lu \n"
8234 " Rectangle x: %ld \n"
8235 " Rectangle y: %ld \n"
8236 " Rectangle dx: %ld \n"
8237 " Rectangle dy: %ld \n",
8238 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8239 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8240 }
8241
8242 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8243 } else if (extra->eType == OMX_ExtraDataNone) {
8244 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8245 } else {
8246 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
Shalaj Jain273b3e02012-06-22 19:08:03 -07008247 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008248}
8249
8250void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008251 OMX_U32 interlaced_format_type)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008252{
Arun Menon906de572013-06-18 17:01:40 -07008253 OMX_STREAMINTERLACEFORMAT *interlace_format;
8254 OMX_U32 mbaff = 0;
8255 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8256 return;
8257 }
8258 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8259 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8260 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8261 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8262 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8263 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8264 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8265 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8266 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8267 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8268 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) {
8269 interlace_format->bInterlaceFormat = OMX_FALSE;
8270 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8271 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8272 } else {
8273 interlace_format->bInterlaceFormat = OMX_TRUE;
8274 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8275 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8276 }
8277 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008278}
8279
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008280void omx_vdec::fill_aspect_ratio_info(
Arun Menon906de572013-06-18 17:01:40 -07008281 struct vdec_aspectratioinfo *aspect_ratio_info,
8282 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008283{
Arun Menon906de572013-06-18 17:01:40 -07008284 m_extradata = frame_info;
8285 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8286 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308287 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioY %lu", m_extradata->aspectRatio.aspectRatioX,
Arun Menon906de572013-06-18 17:01:40 -07008288 m_extradata->aspectRatio.aspectRatioY);
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008289}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008290
8291void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Arun Menon906de572013-06-18 17:01:40 -07008292 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308293 OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008294 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008295{
Arun Menon906de572013-06-18 17:01:40 -07008296 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8297 struct msm_vidc_panscan_window *panscan_window;
8298 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008299 return;
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008300 }
Arun Menon906de572013-06-18 17:01:40 -07008301 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8302 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8303 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8304 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8305 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8306 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8307 switch (picture_type) {
8308 case PICTURE_TYPE_I:
8309 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8310 break;
8311 case PICTURE_TYPE_P:
8312 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8313 break;
8314 case PICTURE_TYPE_B:
8315 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8316 break;
8317 default:
8318 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8319 }
8320 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8321 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8322 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8323 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8324 else
8325 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8326 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8327 frame_info->nConcealedMacroblocks = num_conceal_mb;
8328 frame_info->nFrameRate = frame_rate;
Rajeshwar Kurapaty90a98112013-09-17 16:07:14 +05308329 frame_info->nTimeStamp = time_stamp;
Arun Menon906de572013-06-18 17:01:40 -07008330 frame_info->panScan.numWindows = 0;
8331 if (output_capability == V4L2_PIX_FMT_MPEG2) {
8332 if (m_disp_hor_size && m_disp_vert_size) {
8333 frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8334 frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8335 }
8336 }
Praneeth Paladugud0881ef2013-04-23 23:02:55 -07008337
Arun Menon906de572013-06-18 17:01:40 -07008338 if (panscan_payload) {
8339 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8340 panscan_window = &panscan_payload->wnd[0];
8341 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
8342 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8343 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8344 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8345 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8346 panscan_window++;
8347 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008348 }
Arun Menon906de572013-06-18 17:01:40 -07008349 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8350 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008351}
8352
8353void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8354{
Arun Menon906de572013-06-18 17:01:40 -07008355 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8356 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8357 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8358 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8359 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8360 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8361 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8362 *portDefn = m_port_def;
8363 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8364 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
8365 portDefn->format.video.nFrameWidth,
8366 portDefn->format.video.nStride,
8367 portDefn->format.video.nSliceHeight);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008368}
8369
8370void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8371{
Arun Menon906de572013-06-18 17:01:40 -07008372 if (!client_extradata) {
8373 return;
8374 }
8375 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8376 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8377 extra->eType = OMX_ExtraDataNone;
8378 extra->nDataSize = 0;
8379 extra->data[0] = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008380
Arun Menon906de572013-06-18 17:01:40 -07008381 print_debug_extradata(extra);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008382}
8383
8384OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8385{
Arun Menon906de572013-06-18 17:01:40 -07008386 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8387 if (index >= drv_ctx.ip_buf.actualcount) {
8388 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8389 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008390 }
Arun Menon906de572013-06-18 17:01:40 -07008391 if (m_desc_buffer_ptr == NULL) {
8392 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8393 calloc( (sizeof(desc_buffer_hdr)),
8394 drv_ctx.ip_buf.actualcount);
8395 if (m_desc_buffer_ptr == NULL) {
8396 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8397 return OMX_ErrorInsufficientResources;
8398 }
8399 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008400
Arun Menon906de572013-06-18 17:01:40 -07008401 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8402 if (m_desc_buffer_ptr[index].buf_addr == NULL) {
8403 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8404 return OMX_ErrorInsufficientResources;
8405 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008406
Arun Menon906de572013-06-18 17:01:40 -07008407 return eRet;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008408}
8409
8410void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8411{
Arun Menon906de572013-06-18 17:01:40 -07008412 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
8413 if (m_demux_entries < 8192) {
8414 m_demux_offsets[m_demux_entries++] = address_offset;
8415 }
8416 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008417}
8418
8419void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8420{
Arun Menon906de572013-06-18 17:01:40 -07008421 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8422 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8423 OMX_U32 index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008424
Arun Menon906de572013-06-18 17:01:40 -07008425 m_demux_entries = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008426
Arun Menon906de572013-06-18 17:01:40 -07008427 while (index < bytes_to_parse) {
8428 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8429 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8430 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8431 (buf[index+2] == 0x01)) ) {
8432 //Found start code, insert address offset
8433 insert_demux_addr_offset(index);
8434 if (buf[index+2] == 0x01) // 3 byte start code
8435 index += 3;
8436 else //4 byte start code
8437 index += 4;
8438 } else
8439 index++;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008440 }
Arun Menon906de572013-06-18 17:01:40 -07008441 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
8442 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008443}
8444
8445OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8446{
Arun Menon906de572013-06-18 17:01:40 -07008447 //fix this, handle 3 byte start code, vc1 terminator entry
8448 OMX_U8 *p_demux_data = NULL;
8449 OMX_U32 desc_data = 0;
8450 OMX_U32 start_addr = 0;
8451 OMX_U32 nal_size = 0;
8452 OMX_U32 suffix_byte = 0;
8453 OMX_U32 demux_index = 0;
8454 OMX_U32 buffer_index = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008455
Arun Menon906de572013-06-18 17:01:40 -07008456 if (m_desc_buffer_ptr == NULL) {
8457 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8458 return OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008459 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008460
Arun Menon906de572013-06-18 17:01:40 -07008461 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8462 if (buffer_index > drv_ctx.ip_buf.actualcount) {
8463 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
8464 return OMX_ErrorBadParameter;
8465 }
8466
8467 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8468
8469 if ( ((OMX_U8*)p_demux_data == NULL) ||
8470 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8471 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8472 return OMX_ErrorBadParameter;
8473 } else {
8474 for (; demux_index < m_demux_entries; demux_index++) {
8475 desc_data = 0;
8476 start_addr = m_demux_offsets[demux_index];
8477 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8478 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8479 } else {
8480 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8481 }
8482 if (demux_index < (m_demux_entries - 1)) {
8483 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8484 } else {
8485 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8486 }
8487 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8488 (void *)start_addr,
8489 suffix_byte,
8490 nal_size,
8491 demux_index);
8492 desc_data = (start_addr >> 3) << 1;
8493 desc_data |= (start_addr & 7) << 21;
8494 desc_data |= suffix_byte << 24;
8495
8496 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8497 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8498 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8499 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8500
8501 p_demux_data += 16;
8502 }
8503 if (codec_type_parse == CODEC_TYPE_VC1) {
8504 DEBUG_PRINT_LOW("VC1 terminator entry");
8505 desc_data = 0;
8506 desc_data = 0x82 << 24;
8507 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8508 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8509 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8510 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8511 p_demux_data += 16;
8512 m_demux_entries++;
8513 }
8514 //Add zero word to indicate end of descriptors
8515 memset(p_demux_data, 0, sizeof(OMX_U32));
8516
8517 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8518 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
8519 }
8520 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8521 m_demux_entries = 0;
8522 DEBUG_PRINT_LOW("Demux table complete!");
8523 return OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008524}
8525
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008526OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008527{
Arun Menon906de572013-06-18 17:01:40 -07008528 OMX_ERRORTYPE err = OMX_ErrorNone;
8529 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
8530 if (iDivXDrmDecrypt) {
8531 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8532 if (err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008533 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008534 delete iDivXDrmDecrypt;
8535 iDivXDrmDecrypt = NULL;
Arun Menon906de572013-06-18 17:01:40 -07008536 }
8537 } else {
8538 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
8539 err = OMX_ErrorUndefined;
8540 }
8541 return err;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008542}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008543
Vinay Kaliada4f4422013-01-09 10:45:03 -08008544omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8545{
Arun Menon906de572013-06-18 17:01:40 -07008546 enabled = false;
8547 omx = NULL;
8548 init_members();
8549 ColorFormat = OMX_COLOR_FormatMax;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008550}
8551
8552void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8553{
Arun Menon906de572013-06-18 17:01:40 -07008554 omx = reinterpret_cast<omx_vdec*>(client);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008555}
8556
Arun Menon906de572013-06-18 17:01:40 -07008557void omx_vdec::allocate_color_convert_buf::init_members()
8558{
8559 allocated_count = 0;
8560 buffer_size_req = 0;
8561 buffer_alignment_req = 0;
8562 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8563 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8564 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8565 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008566#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008567 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
Vinay Kaliada4f4422013-01-09 10:45:03 -08008568#endif
Arun Menon906de572013-06-18 17:01:40 -07008569 for (int i = 0; i < MAX_COUNT; i++)
8570 pmem_fd[i] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008571}
8572
Arun Menon906de572013-06-18 17:01:40 -07008573omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
8574{
8575 c2d.destroy();
Vinay Kaliada4f4422013-01-09 10:45:03 -08008576}
8577
8578bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8579{
Arun Menon906de572013-06-18 17:01:40 -07008580 bool status = true;
8581 unsigned int src_size = 0, destination_size = 0;
8582 OMX_COLOR_FORMATTYPE drv_color_format;
8583 if (!omx) {
8584 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8585 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008586 }
Arun Menon906de572013-06-18 17:01:40 -07008587 if (!enabled) {
8588 DEBUG_PRINT_HIGH("\n No color conversion required");
8589 return status;
8590 }
8591 pthread_mutex_lock(&omx->c_lock);
8592 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8593 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8594 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
8595 status = false;
8596 goto fail_update_buf_req;
8597 }
8598 c2d.close();
8599 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8600 omx->drv_ctx.video_resolution.frame_width,
8601 NV12_128m,YCbCr420P);
8602 if (status) {
8603 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8604 if (status)
8605 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8606 }
8607 if (status) {
8608 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8609 !destination_size) {
8610 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
8611 "driver size %d destination size %d",
8612 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8613 status = false;
8614 c2d.close();
8615 buffer_size_req = 0;
8616 } else {
8617 buffer_size_req = destination_size;
8618 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
8619 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
8620 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8621 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
8622 }
8623 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008624fail_update_buf_req:
Arun Menon906de572013-06-18 17:01:40 -07008625 pthread_mutex_unlock(&omx->c_lock);
8626 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008627}
8628
8629bool omx_vdec::allocate_color_convert_buf::set_color_format(
Arun Menon906de572013-06-18 17:01:40 -07008630 OMX_COLOR_FORMATTYPE dest_color_format)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008631{
Arun Menon906de572013-06-18 17:01:40 -07008632 bool status = true;
8633 OMX_COLOR_FORMATTYPE drv_color_format;
8634 if (!omx) {
8635 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8636 return false;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008637 }
Arun Menon906de572013-06-18 17:01:40 -07008638 pthread_mutex_lock(&omx->c_lock);
8639 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8640 drv_color_format = (OMX_COLOR_FORMATTYPE)
8641 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8642 else {
8643 DEBUG_PRINT_ERROR("\n Incorrect color format");
8644 status = false;
8645 }
8646 if (status && (drv_color_format != dest_color_format)) {
8647 DEBUG_PRINT_LOW("Enabling C2D\n");
8648 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
8649 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
8650 status = false;
8651 } else {
8652 ColorFormat = OMX_COLOR_FormatYUV420Planar;
8653 if (enabled)
8654 c2d.destroy();
8655 enabled = false;
8656 if (!c2d.init()) {
8657 DEBUG_PRINT_ERROR("\n open failed for c2d");
8658 status = false;
8659 } else
8660 enabled = true;
8661 }
8662 } else {
8663 if (enabled)
8664 c2d.destroy();
8665 enabled = false;
8666 }
8667 pthread_mutex_unlock(&omx->c_lock);
8668 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008669}
8670
8671OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
8672{
Arun Menon906de572013-06-18 17:01:40 -07008673 if (!omx) {
8674 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8675 return NULL;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008676 }
Arun Menon906de572013-06-18 17:01:40 -07008677 if (!enabled)
8678 return omx->m_out_mem_ptr;
8679 return m_out_mem_ptr_client;
8680}
8681
8682 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
8683(OMX_BUFFERHEADERTYPE *bufadd)
8684{
8685 if (!omx) {
8686 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8687 return NULL;
8688 }
8689 if (!enabled)
8690 return bufadd;
8691
8692 unsigned index = 0;
8693 index = bufadd - omx->m_out_mem_ptr;
8694 if (index < omx->drv_ctx.op_buf.actualcount) {
8695 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
8696 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
8697 bool status;
8698 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
8699 pthread_mutex_lock(&omx->c_lock);
8700 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
8701 omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
8702 pmem_baseaddress[index], pmem_baseaddress[index]);
8703 pthread_mutex_unlock(&omx->c_lock);
8704 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
8705 if (!status) {
8706 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
8707 m_out_mem_ptr_client[index].nFilledLen = 0;
8708 return &m_out_mem_ptr_client[index];
8709 }
8710 } else
8711 m_out_mem_ptr_client[index].nFilledLen = 0;
8712 return &m_out_mem_ptr_client[index];
8713 }
8714 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
8715 return NULL;
8716}
8717
8718 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
8719(OMX_BUFFERHEADERTYPE *bufadd)
8720{
8721 if (!omx) {
8722 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
8723 return NULL;
8724 }
8725 if (!enabled)
8726 return bufadd;
8727 unsigned index = 0;
8728 index = bufadd - m_out_mem_ptr_client;
8729 if (index < omx->drv_ctx.op_buf.actualcount) {
8730 return &omx->m_out_mem_ptr[index];
8731 }
8732 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
8733 return NULL;
8734}
8735 bool omx_vdec::allocate_color_convert_buf::get_buffer_req
8736(unsigned int &buffer_size)
8737{
8738 bool status = true;
8739 pthread_mutex_lock(&omx->c_lock);
8740 if (!enabled)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008741 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Arun Menon906de572013-06-18 17:01:40 -07008742 else {
8743 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
8744 DEBUG_PRINT_ERROR("\n Get buffer size failed");
8745 status = false;
8746 goto fail_get_buffer_size;
8747 }
8748 }
8749 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
8750 buffer_size = omx->drv_ctx.op_buf.buffer_size;
8751 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
8752 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008753fail_get_buffer_size:
Arun Menon906de572013-06-18 17:01:40 -07008754 pthread_mutex_unlock(&omx->c_lock);
8755 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008756}
8757OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
Arun Menon906de572013-06-18 17:01:40 -07008758 OMX_BUFFERHEADERTYPE *bufhdr)
8759{
8760 unsigned int index = 0;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008761
Arun Menon906de572013-06-18 17:01:40 -07008762 if (!enabled)
8763 return omx->free_output_buffer(bufhdr);
8764 if (enabled && omx->is_component_secure())
8765 return OMX_ErrorNone;
8766 if (!allocated_count || !bufhdr) {
8767 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
8768 return OMX_ErrorBadParameter;
8769 }
8770 index = bufhdr - m_out_mem_ptr_client;
8771 if (index >= omx->drv_ctx.op_buf.actualcount) {
8772 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
8773 return OMX_ErrorBadParameter;
8774 }
8775 if (pmem_fd[index] > 0) {
8776 munmap(pmem_baseaddress[index], buffer_size_req);
8777 close(pmem_fd[index]);
8778 }
8779 pmem_fd[index] = -1;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008780#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008781 omx->free_ion_memory(&op_buf_ion_info[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008782#endif
Arun Menon906de572013-06-18 17:01:40 -07008783 m_heap_ptr[index].video_heap_ptr = NULL;
8784 if (allocated_count > 0)
8785 allocated_count--;
8786 else
8787 allocated_count = 0;
8788 if (!allocated_count) {
8789 pthread_mutex_lock(&omx->c_lock);
8790 c2d.close();
8791 init_members();
8792 pthread_mutex_unlock(&omx->c_lock);
8793 }
8794 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008795}
8796
8797OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
Arun Menon906de572013-06-18 17:01:40 -07008798 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
Vinay Kaliada4f4422013-01-09 10:45:03 -08008799{
Arun Menon906de572013-06-18 17:01:40 -07008800 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8801 if (!enabled) {
8802 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
8803 return eRet;
8804 }
8805 if (enabled && omx->is_component_secure()) {
8806 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
8807 omx->is_component_secure());
8808 return OMX_ErrorUnsupportedSetting;
8809 }
8810 if (!bufferHdr || bytes > buffer_size_req) {
8811 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
8812 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
8813 buffer_size_req,bytes);
8814 return OMX_ErrorBadParameter;
8815 }
8816 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
8817 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
8818 return OMX_ErrorInsufficientResources;
8819 }
8820 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
8821 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
8822 port,appData,omx->drv_ctx.op_buf.buffer_size);
8823 if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
8824 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
8825 return eRet;
8826 }
8827 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
8828 omx->drv_ctx.op_buf.actualcount) {
8829 DEBUG_PRINT_ERROR("\n Invalid header index %d",
8830 (temp_bufferHdr - omx->m_out_mem_ptr));
8831 return OMX_ErrorUndefined;
8832 }
8833 unsigned int i = allocated_count;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008834#ifdef USE_ION
Arun Menon906de572013-06-18 17:01:40 -07008835 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
8836 buffer_size_req,buffer_alignment_req,
8837 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
8838 0);
8839 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
8840 if (op_buf_ion_info[i].ion_device_fd < 0) {
8841 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
8842 return OMX_ErrorInsufficientResources;
8843 }
8844 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
8845 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008846
Arun Menon906de572013-06-18 17:01:40 -07008847 if (pmem_baseaddress[i] == MAP_FAILED) {
8848 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
8849 close(pmem_fd[i]);
8850 omx->free_ion_memory(&op_buf_ion_info[i]);
8851 return OMX_ErrorInsufficientResources;
8852 }
8853 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
8854 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
8855 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008856#endif
Arun Menon906de572013-06-18 17:01:40 -07008857 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
8858 m_pmem_info_client[i].offset = 0;
8859 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
8860 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8861 m_platform_list_client[i].nEntries = 1;
8862 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
8863 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
8864 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
8865 m_out_mem_ptr_client[i].nFilledLen = 0;
8866 m_out_mem_ptr_client[i].nFlags = 0;
8867 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8868 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
8869 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
8870 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
8871 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
8872 m_out_mem_ptr_client[i].pAppPrivate = appData;
8873 *bufferHdr = &m_out_mem_ptr_client[i];
8874 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
8875 allocated_count++;
8876 return eRet;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008877}
8878
8879bool omx_vdec::is_component_secure()
8880{
Arun Menon906de572013-06-18 17:01:40 -07008881 return secure_mode;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008882}
8883
8884bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
8885{
Arun Menon906de572013-06-18 17:01:40 -07008886 bool status = true;
8887 if (!enabled) {
8888 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
8889 dest_color_format = (OMX_COLOR_FORMATTYPE)
8890 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
8891 else
8892 status = false;
8893 } else {
8894 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8895 status = false;
8896 } else
8897 dest_color_format = OMX_COLOR_FormatYUV420Planar;
8898 }
8899 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008900}
Arun Menonbdb80b02013-08-12 17:45:54 -07008901
8902#ifdef META_DATA_MODE_SUPPORTED
8903void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
8904{
8905 int i = 0;
8906 bool buf_present = false;
8907 pthread_mutex_lock(&m_lock);
8908 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
8909 //check the buffer fd, offset, uv addr with list contents
8910 //If present increment reference.
8911 if ((out_dynamic_list[i].fd == fd) &&
8912 (out_dynamic_list[i].offset == offset)) {
8913 out_dynamic_list[i].ref_count++;
8914 DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d\n",
8915 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
8916 buf_present = true;
8917 break;
8918 }
8919 }
8920 if (!buf_present) {
8921 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
8922 //search for a entry to insert details of the new buffer
8923 if (out_dynamic_list[i].dup_fd == 0) {
8924 out_dynamic_list[i].fd = fd;
8925 out_dynamic_list[i].offset = offset;
8926 out_dynamic_list[i].dup_fd = dup(fd);
8927 out_dynamic_list[i].ref_count++;
8928 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d\n",
8929 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
8930 break;
8931 }
8932 }
8933 }
8934 pthread_mutex_unlock(&m_lock);
8935}
8936
8937void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
8938{
8939 int i = 0;
8940 pthread_mutex_lock(&m_lock);
8941 for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
8942 //check the buffer fd, offset, uv addr with list contents
8943 //If present decrement reference.
8944 if ((out_dynamic_list[i].fd == fd) &&
8945 (out_dynamic_list[i].offset == offset)) {
8946 out_dynamic_list[i].ref_count--;
8947 if (out_dynamic_list[i].ref_count == 0) {
8948 close(out_dynamic_list[i].dup_fd);
8949 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d\n",
8950 out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
8951 out_dynamic_list[i].dup_fd = 0;
8952 out_dynamic_list[i].fd = 0;
8953 out_dynamic_list[i].offset = 0;
8954 }
8955 break;
8956 }
8957 }
8958 if (i >= drv_ctx.op_buf.actualcount) {
8959 DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list\n");
8960 }
8961 pthread_mutex_unlock(&m_lock);
8962}
8963#endif