blob: cea3bb9432e72068eaee956061cf4273e87fe801 [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>
Vinay Kaliada8f3cf2012-12-21 18:26:21 -080051#include <media/msm_media_info.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070052
53#ifndef _ANDROID_
54#include <sys/ioctl.h>
55#include <sys/mman.h>
56#endif //_ANDROID_
57
58#ifdef _ANDROID_
59#include <cutils/properties.h>
60#undef USE_EGL_IMAGE_GPU
61#endif
62
63#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
64#include <gralloc_priv.h>
65#endif
66
67#if defined (_ANDROID_ICS_)
68#include <genlock.h>
Vinay Kalia0e75e9a2012-09-27 15:41:53 -070069#include <qdMetaData.h>
Shalaj Jain273b3e02012-06-22 19:08:03 -070070#endif
71
72#ifdef _ANDROID_
73#include "DivXDrmDecrypt.h"
74#endif //_ANDROID_
75
76#ifdef USE_EGL_IMAGE_GPU
77#include <EGL/egl.h>
78#include <EGL/eglQCOM.h>
79#define EGL_BUFFER_HANDLE_QCOM 0x4F00
80#define EGL_BUFFER_OFFSET_QCOM 0x4F01
81#endif
82
83#ifdef INPUT_BUFFER_LOG
84#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0"
85#define INPUT_BUFFER_FILE_NAME_LEN 30
86FILE *inputBufferFile1;
87char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
88#endif
89#ifdef OUTPUT_BUFFER_LOG
90FILE *outputBufferFile1;
91char outputfilename [] = "/data/output.yuv";
92#endif
93#ifdef OUTPUT_EXTRADATA_LOG
94FILE *outputExtradataFile;
95char ouputextradatafilename [] = "/data/extradata";
96#endif
97
98#define DEFAULT_FPS 30
99#define MAX_INPUT_ERROR DEFAULT_FPS
100#define MAX_SUPPORTED_FPS 120
101
102#define VC1_SP_MP_START_CODE 0xC5000000
103#define VC1_SP_MP_START_CODE_MASK 0xFF000000
104#define VC1_AP_SEQ_START_CODE 0x0F010000
105#define VC1_STRUCT_C_PROFILE_MASK 0xF0
106#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
107#define VC1_SIMPLE_PROFILE 0
108#define VC1_MAIN_PROFILE 1
109#define VC1_ADVANCE_PROFILE 3
110#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
111#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
112#define VC1_STRUCT_C_LEN 4
113#define VC1_STRUCT_C_POS 8
114#define VC1_STRUCT_A_POS 12
115#define VC1_STRUCT_B_POS 24
116#define VC1_SEQ_LAYER_SIZE 36
Vinay Kaliab09886c2012-08-20 11:27:25 -0700117#define POLL_TIMEOUT 0x7fffffff
Shalaj Jain273b3e02012-06-22 19:08:03 -0700118
119#define MEM_DEVICE "/dev/ion"
120#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
121
122#ifdef _ANDROID_
123 extern "C"{
124 #include<utils/Log.h>
125 }
126#endif//_ANDROID_
127
Vinay Kalia53fa6832012-10-11 17:55:30 -0700128#define SZ_4K 0x1000
129#define SZ_1M 0x100000
130
Shalaj Jain273b3e02012-06-22 19:08:03 -0700131#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
132#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 -0700133#define EXTRADATA_IDX(__num_planes) (__num_planes - 1)
134
Vinay Kaliadb90f8c2012-11-19 18:57:56 -0800135#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700136void* async_message_thread (void *input)
137{
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700138 OMX_BUFFERHEADERTYPE *buffer;
139 struct v4l2_plane plane[VIDEO_MAX_PLANES];
140 struct pollfd pfd;
Praneeth Paladugu32284302013-02-14 22:53:06 -0800141 struct v4l2_buffer v4l2_buf;
142 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700143 struct v4l2_event dqevent;
144 omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
145 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
146 pfd.fd = omx->drv_ctx.video_driver_fd;
147 int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
148 DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
149 prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
150 while (1)
151 {
152 rc = poll(&pfd, 1, POLL_TIMEOUT);
153 if (!rc) {
154 DEBUG_PRINT_ERROR("Poll timedout\n");
155 break;
156 } else if (rc < 0) {
157 DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
158 break;
159 }
160 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
161 struct vdec_msginfo vdec_msg;
162 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
163 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
164 v4l2_buf.length = omx->drv_ctx.num_planes;
165 v4l2_buf.m.planes = plane;
166 while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
167 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
168 vdec_msg.status_code=VDEC_S_SUCCESS;
169 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
170 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
171 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
Eric (Quicee1674a2012-12-21 15:29:08 -0800172 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
173 (uint64_t)v4l2_buf.timestamp.tv_usec;
Vinay Kalia592e4b42012-12-19 15:55:47 -0800174 if (vdec_msg.msgdata.output_frame.len) {
175 vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
176 vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
177 vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
178 vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
179 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700180 if (omx->async_message_process(input,&vdec_msg) < 0) {
181 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
182 break;
183 }
184 }
185 }
186 if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
187 struct vdec_msginfo vdec_msg;
188 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
189 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
190 v4l2_buf.length = 1;
191 v4l2_buf.m.planes = plane;
192 while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
193 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
194 vdec_msg.status_code=VDEC_S_SUCCESS;
195 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
196 if (omx->async_message_process(input,&vdec_msg) < 0) {
197 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
198 break;
199 }
200 }
201 }
202 if (pfd.revents & POLLPRI){
203 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
Praneeth Paladugu1662ca62012-10-15 13:27:16 -0700204 if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700205 struct vdec_msginfo vdec_msg;
206 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
207 vdec_msg.status_code=VDEC_S_SUCCESS;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -0700208 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved \n");
209 if (omx->async_message_process(input,&vdec_msg) < 0) {
210 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
211 break;
212 }
213 } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT ) {
214 struct vdec_msginfo vdec_msg;
215 vdec_msg.msgcode=VDEC_MSG_EVT_INFO_CONFIG_CHANGED;
216 vdec_msg.status_code=VDEC_S_SUCCESS;
217 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved \n");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700218 if (omx->async_message_process(input,&vdec_msg) < 0) {
219 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
220 break;
221 }
222 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
223 struct vdec_msginfo vdec_msg;
224 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
225 vdec_msg.status_code=VDEC_S_SUCCESS;
226 DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n");
227 if (omx->async_message_process(input,&vdec_msg) < 0) {
228 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
229 break;
230 }
231 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
232 vdec_msg.status_code=VDEC_S_SUCCESS;
233 DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n");
234 if (omx->async_message_process(input,&vdec_msg) < 0) {
235 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
236 break;
237 }
238 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
239 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
240 break;
241 } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
242 struct vdec_msginfo vdec_msg;
243 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
244 vdec_msg.status_code=VDEC_S_SUCCESS;
245 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
246 if (omx->async_message_process(input,&vdec_msg) < 0) {
247 DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
248 break;
249 }
250 } else {
251 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
252 continue;
253 }
254 }
255 }
256 DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
257 return NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700258}
259
260void* message_thread(void *input)
261{
262 omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
263 unsigned char id;
264 int n;
265
266 DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
267 prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
268 while (1)
269 {
270
271 n = read(omx->m_pipe_in, &id, 1);
272
273 if(0 == n)
274 {
275 break;
276 }
277
278 if (1 == n)
279 {
280 omx->process_event_cb(omx, id);
281 }
282 if ((n < 0) && (errno != EINTR))
283 {
284 DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
285 break;
286 }
287 }
288 DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
289 return 0;
290}
291
292void post_message(omx_vdec *omx, unsigned char id)
293{
294 int ret_value;
295 DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
296 ret_value = write(omx->m_pipe_out, &id, 1);
297 DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
298}
299
300// omx_cmd_queue destructor
301omx_vdec::omx_cmd_queue::~omx_cmd_queue()
302{
303 // Nothing to do
304}
305
306// omx cmd queue constructor
307omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
308{
309 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
310}
311
312// omx cmd queue insert
313bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
314{
315 bool ret = true;
316 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
317 {
318 m_q[m_write].id = id;
319 m_q[m_write].param1 = p1;
320 m_q[m_write].param2 = p2;
321 m_write++;
322 m_size ++;
323 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
324 {
325 m_write = 0;
326 }
327 }
328 else
329 {
330 ret = false;
331 DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
332 }
333 return ret;
334}
335
336// omx cmd queue pop
337bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
338{
339 bool ret = true;
340 if (m_size > 0)
341 {
342 *id = m_q[m_read].id;
343 *p1 = m_q[m_read].param1;
344 *p2 = m_q[m_read].param2;
345 // Move the read pointer ahead
346 ++m_read;
347 --m_size;
348 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
349 {
350 m_read = 0;
351 }
352 }
353 else
354 {
355 ret = false;
356 }
357 return ret;
358}
359
360// Retrieve the first mesg type in the queue
361unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
362{
363 return m_q[m_read].id;
364}
365
366#ifdef _ANDROID_
367omx_vdec::ts_arr_list::ts_arr_list()
368{
369 //initialize timestamps array
370 memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
371}
372omx_vdec::ts_arr_list::~ts_arr_list()
373{
374 //free m_ts_arr_list?
375}
376
377bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
378{
379 bool ret = true;
380 bool duplicate_ts = false;
381 int idx = 0;
382
383 //insert at the first available empty location
384 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
385 {
386 if (!m_ts_arr_list[idx].valid)
387 {
388 //found invalid or empty entry, save timestamp
389 m_ts_arr_list[idx].valid = true;
390 m_ts_arr_list[idx].timestamp = ts;
391 DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
392 ts, idx);
393 break;
394 }
395 }
396
397 if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS)
398 {
399 DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
400 ret = false;
401 }
402 return ret;
403}
404
405bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
406{
407 bool ret = true;
408 int min_idx = -1;
409 OMX_TICKS min_ts = 0;
410 int idx = 0;
411
412 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
413 {
414
415 if (m_ts_arr_list[idx].valid)
416 {
417 //found valid entry, save index
418 if (min_idx < 0)
419 {
420 //first valid entry
421 min_ts = m_ts_arr_list[idx].timestamp;
422 min_idx = idx;
423 }
424 else if (m_ts_arr_list[idx].timestamp < min_ts)
425 {
426 min_ts = m_ts_arr_list[idx].timestamp;
427 min_idx = idx;
428 }
429 }
430
431 }
432
433 if (min_idx < 0)
434 {
435 //no valid entries found
436 DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
437 ts = 0;
438 ret = false;
439 }
440 else
441 {
442 ts = m_ts_arr_list[min_idx].timestamp;
443 m_ts_arr_list[min_idx].valid = false;
444 DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
445 ts, min_idx);
446 }
447
448 return ret;
449
450}
451
452
453bool omx_vdec::ts_arr_list::reset_ts_list()
454{
455 bool ret = true;
456 int idx = 0;
457
458 DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
459 for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
460 {
461 m_ts_arr_list[idx].valid = false;
462 }
463 return ret;
464}
465#endif
466
467// factory function executed by the core to create instances
468void *get_omx_component_factory_fn(void)
469{
470 return (new omx_vdec);
471}
472
473#ifdef _ANDROID_
474#ifdef USE_ION
475VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
476 struct ion_handle *handle, int ionMapfd)
477{
Ashray Kulkarni69a930f2012-07-30 12:31:40 -0700478// ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700479}
480#else
481VideoHeap::VideoHeap(int fd, size_t size, void* base)
482{
483 // dup file descriptor, map once, use pmem
484 init(dup(fd), base, size, 0 , MEM_DEVICE);
485}
486#endif
487#endif // _ANDROID_
488/* ======================================================================
489FUNCTION
490 omx_vdec::omx_vdec
491
492DESCRIPTION
493 Constructor
494
495PARAMETERS
496 None
497
498RETURN VALUE
499 None.
500========================================================================== */
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800501omx_vdec::omx_vdec(): m_error_propogated(false),
502 m_state(OMX_StateInvalid),
503 m_app_data(NULL),
504 m_inp_mem_ptr(NULL),
505 m_out_mem_ptr(NULL),
506 m_inp_err_count(0),
507 input_flush_progress (false),
508 output_flush_progress (false),
509 input_use_buffer (false),
510 output_use_buffer (false),
511 ouput_egl_buffers(false),
512 m_use_output_pmem(OMX_FALSE),
513 m_out_mem_region_smi(OMX_FALSE),
514 m_out_pvt_entry_pmem(OMX_FALSE),
515 pending_input_buffers(0),
516 pending_output_buffers(0),
517 m_out_bm_count(0),
518 m_inp_bm_count(0),
519 m_inp_bPopulated(OMX_FALSE),
520 m_out_bPopulated(OMX_FALSE),
521 m_flags(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700522#ifdef _ANDROID_
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800523 m_heap_ptr(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700524#endif
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800525 m_inp_bEnabled(OMX_TRUE),
526 m_out_bEnabled(OMX_TRUE),
527 m_in_alloc_cnt(0),
528 m_platform_list(NULL),
529 m_platform_entry(NULL),
530 m_pmem_info(NULL),
531 arbitrary_bytes (true),
532 psource_frame (NULL),
533 pdest_frame (NULL),
534 m_inp_heap_ptr (NULL),
535 m_phdr_pmem_ptr(NULL),
536 m_heap_inp_bm_count (0),
537 codec_type_parse ((codec_type)0),
538 first_frame_meta (true),
539 frame_count (0),
540 nal_count (0),
541 nal_length(0),
542 look_ahead_nal (false),
543 first_frame(0),
544 first_buffer(NULL),
545 first_frame_size (0),
546 m_device_file_ptr(NULL),
547 m_vc1_profile((vc1_profile_type)0),
548 h264_last_au_ts(LLONG_MAX),
549 h264_last_au_flags(0),
550 prev_ts(LLONG_MAX),
551 rst_prev_ts(true),
552 frm_int(0),
553 in_reconfig(false),
554 m_display_id(NULL),
555 h264_parser(NULL),
556 client_extradata(0),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700557#ifdef _ANDROID_
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800558 m_enable_android_native_buffers(OMX_FALSE),
559 m_use_android_native_buffers(OMX_FALSE),
560 iDivXDrmDecrypt(NULL),
Shalaj Jain273b3e02012-06-22 19:08:03 -0700561#endif
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800562 m_desc_buffer_ptr(NULL),
563 secure_mode(false)
Shalaj Jain273b3e02012-06-22 19:08:03 -0700564{
565 /* Assumption is that , to begin with , we have all the frames with decoder */
566 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
567#ifdef _ANDROID_
568 char property_value[PROPERTY_VALUE_MAX] = {0};
569 property_get("vidc.dec.debug.perf", property_value, "0");
570 perf_flag = atoi(property_value);
571 if (perf_flag)
572 {
573 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
574 dec_time.start();
575 proc_frms = latency = 0;
576 }
Shalaj Jain286b0062013-02-21 20:35:48 -0800577 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700578 property_get("vidc.dec.debug.ts", property_value, "0");
579 m_debug_timestamp = atoi(property_value);
580 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
581 if (m_debug_timestamp)
582 {
583 time_stamp_dts.set_timestamp_reorder_mode(true);
Praneeth Paladugu451eec92013-01-31 22:45:45 -0800584 time_stamp_dts.enable_debug_print(true);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700585 }
586
Shalaj Jain286b0062013-02-21 20:35:48 -0800587 property_value[0] = '\0';
Shalaj Jain273b3e02012-06-22 19:08:03 -0700588 property_get("vidc.dec.debug.concealedmb", property_value, "0");
589 m_debug_concealedmb = atoi(property_value);
590 DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
591
592#endif
593 memset(&m_cmp,0,sizeof(m_cmp));
594 memset(&m_cb,0,sizeof(m_cb));
595 memset (&drv_ctx,0,sizeof(drv_ctx));
596 memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
597 memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700598 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
599 m_demux_entries = 0;
600#ifdef _ANDROID_ICS_
601 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
602#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -0700603 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
Shalaj Jain273b3e02012-06-22 19:08:03 -0700604 drv_ctx.timestamp_adjust = false;
605 drv_ctx.video_driver_fd = -1;
606 m_vendor_config.pData = NULL;
607 pthread_mutex_init(&m_lock, NULL);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800608 pthread_mutex_init(&c_lock, NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700609 sem_init(&m_cmd_lock,0,0);
Deva Ramasubramanian5c241242013-02-19 17:25:30 -0800610 streaming[CAPTURE_PORT] =
611 streaming[OUTPUT_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700612#ifdef _ANDROID_
613 char extradata_value[PROPERTY_VALUE_MAX] = {0};
614 property_get("vidc.dec.debug.extradata", extradata_value, "0");
615 m_debug_extradata = atoi(extradata_value);
616 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
617#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -0800618 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
619 client_buffers.set_vdec_client(this);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700620}
621
Vinay Kalia85793762012-06-14 19:12:34 -0700622static const int event_type[] = {
623 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
624 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
625 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Praneeth Paladugu268314a2012-08-23 11:33:28 -0700626 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
627 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700628};
629
630static OMX_ERRORTYPE subscribe_to_events(int fd)
631{
632 OMX_ERRORTYPE eRet = OMX_ErrorNone;
633 struct v4l2_event_subscription sub;
634 int array_sz = sizeof(event_type)/sizeof(int);
635 int i,rc;
636 if (fd < 0) {
637 printf("Invalid input: %d\n", fd);
638 return OMX_ErrorBadParameter;
639 }
640
641 for (i = 0; i < array_sz; ++i) {
642 memset(&sub, 0, sizeof(sub));
643 sub.type = event_type[i];
644 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
645 if (rc) {
646 printf("Failed to subscribe event: 0x%x\n", sub.type);
647 break;
648 }
649 }
650 if (i < array_sz) {
651 for (--i; i >=0 ; i--) {
652 memset(&sub, 0, sizeof(sub));
653 sub.type = event_type[i];
654 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
655 if (rc)
656 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
657 }
658 eRet = OMX_ErrorNotImplemented;
659 }
660 return eRet;
661}
662
663
664static OMX_ERRORTYPE unsubscribe_to_events(int fd)
665{
666 OMX_ERRORTYPE eRet = OMX_ErrorNone;
667 struct v4l2_event_subscription sub;
668 int array_sz = sizeof(event_type)/sizeof(int);
669 int i,rc;
670 if (fd < 0) {
671 printf("Invalid input: %d\n", fd);
672 return OMX_ErrorBadParameter;
673 }
674
675 for (i = 0; i < array_sz; ++i) {
676 memset(&sub, 0, sizeof(sub));
677 sub.type = event_type[i];
678 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
679 if (rc) {
680 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
681 break;
682 }
683 }
684 return eRet;
685}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700686
687/* ======================================================================
688FUNCTION
689 omx_vdec::~omx_vdec
690
691DESCRIPTION
692 Destructor
693
694PARAMETERS
695 None
696
697RETURN VALUE
698 None.
699========================================================================== */
700omx_vdec::~omx_vdec()
701{
702 m_pmem_info = NULL;
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700703 struct v4l2_decoder_cmd dec;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700704 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
705 if(m_pipe_in) close(m_pipe_in);
706 if(m_pipe_out) close(m_pipe_out);
707 m_pipe_in = -1;
708 m_pipe_out = -1;
709 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
710 pthread_join(msg_thread_id,NULL);
711 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700712 dec.cmd = V4L2_DEC_CMD_STOP;
713 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
714 {
715 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
716 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700717 pthread_join(async_thread_id,NULL);
Vinay Kalia85793762012-06-14 19:12:34 -0700718 unsubscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700719 close(drv_ctx.video_driver_fd);
720 pthread_mutex_destroy(&m_lock);
Praneeth Paladuguf6995272013-02-04 14:03:56 -0800721 pthread_mutex_destroy(&c_lock);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700722 sem_destroy(&m_cmd_lock);
723 if (perf_flag)
724 {
725 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
726 dec_time.end();
727 }
728 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
729}
730
Vinay Kaliafeef7032012-09-25 19:23:33 -0700731int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) {
732 struct v4l2_requestbuffers bufreq;
733 int rc = 0;
734 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
735 bufreq.memory = V4L2_MEMORY_USERPTR;
736 bufreq.count = 0;
737 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
738 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
739 }
740 return rc;
741}
742
Shalaj Jain273b3e02012-06-22 19:08:03 -0700743/* ======================================================================
744FUNCTION
745 omx_vdec::OMXCntrlProcessMsgCb
746
747DESCRIPTION
748 IL Client callbacks are generated through this routine. The decoder
749 provides the thread context for this routine.
750
751PARAMETERS
752 ctxt -- Context information related to the self.
753 id -- Event identifier. This could be any of the following:
754 1. Command completion event
755 2. Buffer done callback event
756 3. Frame done callback event
757
758RETURN VALUE
759 None.
760
761========================================================================== */
762void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
763{
Shalaj Jain286b0062013-02-21 20:35:48 -0800764 signed p1; // Parameter - 1
765 signed p2; // Parameter - 2
Shalaj Jain273b3e02012-06-22 19:08:03 -0700766 unsigned ident;
767 unsigned qsize=0; // qsize
768 omx_vdec *pThis = (omx_vdec *) ctxt;
769
770 if(!pThis)
771 {
772 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
773 __func__);
774 return;
775 }
776
777 // Protect the shared queue data structure
778 do
779 {
780 /*Read the message id's from the queue*/
781 pthread_mutex_lock(&pThis->m_lock);
782 qsize = pThis->m_cmd_q.m_size;
783 if(qsize)
784 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800785 pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700786 }
787
788 if (qsize == 0 && pThis->m_state != OMX_StatePause)
789 {
790 qsize = pThis->m_ftb_q.m_size;
791 if (qsize)
792 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800793 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700794 }
795 }
796
797 if (qsize == 0 && pThis->m_state != OMX_StatePause)
798 {
799 qsize = pThis->m_etb_q.m_size;
800 if (qsize)
801 {
Shalaj Jain286b0062013-02-21 20:35:48 -0800802 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700803 }
804 }
805 pthread_mutex_unlock(&pThis->m_lock);
806
807 /*process message if we have one*/
808 if(qsize > 0)
809 {
810 id = ident;
811 switch (id)
812 {
813 case OMX_COMPONENT_GENERATE_EVENT:
814 if (pThis->m_cb.EventHandler)
815 {
816 switch (p1)
817 {
818 case OMX_CommandStateSet:
819 pThis->m_state = (OMX_STATETYPE) p2;
820 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
821 pThis->m_state);
822 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
823 OMX_EventCmdComplete, p1, p2, NULL);
824 break;
825
826 case OMX_EventError:
827 if(p2 == OMX_StateInvalid)
828 {
829 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
830 pThis->m_state = (OMX_STATETYPE) p2;
831 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
832 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
833 }
834 else if (p2 == OMX_ErrorHardware)
835 {
836 pThis->omx_report_error();
837 }
838 else
839 {
840 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Shalaj Jain286b0062013-02-21 20:35:48 -0800841 OMX_EventError, p2, (OMX_U32)NULL, NULL );
Shalaj Jain273b3e02012-06-22 19:08:03 -0700842 }
843 break;
844
845 case OMX_CommandPortDisable:
846 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
847 if (BITMASK_PRESENT(&pThis->m_flags,
848 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
849 {
850 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
851 break;
852 }
853 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig)
854 {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700855 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -0700856 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Vinay Kaliafeef7032012-09-25 19:23:33 -0700857 if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
858 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
859 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700860 pThis->in_reconfig = false;
861 if(eRet != OMX_ErrorNone)
862 {
863 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
864 pThis->omx_report_error();
865 break;
866 }
867 }
868 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
869 OMX_EventCmdComplete, p1, p2, NULL );
870 break;
871 case OMX_CommandPortEnable:
872 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
873 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
874 OMX_EventCmdComplete, p1, p2, NULL );
875 break;
876
877 default:
878 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
879 OMX_EventCmdComplete, p1, p2, NULL );
880 break;
881
882 }
883 }
884 else
885 {
886 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
887 }
888 break;
889 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
890 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
891 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
892 {
893 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
894 pThis->omx_report_error ();
895 }
896 break;
897 case OMX_COMPONENT_GENERATE_ETB:
898 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
899 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
900 {
901 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
902 pThis->omx_report_error ();
903 }
904 break;
905
906 case OMX_COMPONENT_GENERATE_FTB:
907 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
908 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
909 {
910 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
911 pThis->omx_report_error ();
912 }
913 break;
914
915 case OMX_COMPONENT_GENERATE_COMMAND:
916 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
917 (OMX_U32)p2,(OMX_PTR)NULL);
918 break;
919
920 case OMX_COMPONENT_GENERATE_EBD:
921
922 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR)
923 {
924 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
925 pThis->omx_report_error ();
926 }
927 else
928 {
929 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1)
930 {
931 pThis->m_inp_err_count++;
932 pThis->time_stamp_dts.remove_time_stamp(
933 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
934 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
935 ?true:false);
936 }
937 else
938 {
939 pThis->m_inp_err_count = 0;
940 }
941 if ( pThis->empty_buffer_done(&pThis->m_cmp,
942 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
943 {
944 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
945 pThis->omx_report_error ();
946 }
947 if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
948 {
949 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
950 pThis->omx_report_error ();
951 }
952 }
953 break;
954 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED:
955 {
956 int64_t *timestamp = (int64_t *)p1;
957 if (p1)
958 {
959 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
960 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
961 ?true:false);
962 free(timestamp);
963 }
964 }
965 break;
966 case OMX_COMPONENT_GENERATE_FBD:
967 if (p2 != VDEC_S_SUCCESS)
968 {
969 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
970 pThis->omx_report_error ();
971 }
972 else if ( pThis->fill_buffer_done(&pThis->m_cmp,
973 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
974 {
975 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
976 pThis->omx_report_error ();
977 }
978 break;
979
980 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
981 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
982 if (!pThis->input_flush_progress)
983 {
984 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
985 }
986 else
987 {
988 pThis->execute_input_flush();
989 if (pThis->m_cb.EventHandler)
990 {
991 if (p2 != VDEC_S_SUCCESS)
992 {
993 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
994 pThis->omx_report_error ();
995 }
996 else
997 {
998 /*Check if we need generate event for Flush done*/
999 if(BITMASK_PRESENT(&pThis->m_flags,
1000 OMX_COMPONENT_INPUT_FLUSH_PENDING))
1001 {
1002 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
1003 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
1004 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1005 OMX_EventCmdComplete,OMX_CommandFlush,
1006 OMX_CORE_INPUT_PORT_INDEX,NULL );
1007 }
1008 if (BITMASK_PRESENT(&pThis->m_flags,
1009 OMX_COMPONENT_IDLE_PENDING))
1010 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001011 if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001012 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
1013 pThis->omx_report_error ();
1014 } else {
1015 pThis->streaming[OUTPUT_PORT] = false;
1016 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001017 if (!pThis->output_flush_progress)
1018 {
Vinay Kalia22046272012-09-28 20:16:05 -07001019 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001020 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001021 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001022 }
1023 }
1024 }
1025 }
1026 else
1027 {
1028 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1029 }
1030 }
1031 break;
1032
1033 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1034 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
1035 if (!pThis->output_flush_progress)
1036 {
1037 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
1038 }
1039 else
1040 {
1041 pThis->execute_output_flush();
1042 if (pThis->m_cb.EventHandler)
1043 {
1044 if (p2 != VDEC_S_SUCCESS)
1045 {
1046 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1047 pThis->omx_report_error ();
1048 }
1049 else
1050 {
1051 /*Check if we need generate event for Flush done*/
1052 if(BITMASK_PRESENT(&pThis->m_flags,
1053 OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
1054 {
1055 DEBUG_PRINT_LOW("\n Notify Output Flush done");
1056 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1057 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1058 OMX_EventCmdComplete,OMX_CommandFlush,
1059 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1060 }
1061 if(BITMASK_PRESENT(&pThis->m_flags,
1062 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
1063 {
1064 DEBUG_PRINT_LOW("\n Internal flush complete");
1065 BITMASK_CLEAR (&pThis->m_flags,
1066 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1067 if (BITMASK_PRESENT(&pThis->m_flags,
1068 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED))
1069 {
1070 pThis->post_event(OMX_CommandPortDisable,
1071 OMX_CORE_OUTPUT_PORT_INDEX,
1072 OMX_COMPONENT_GENERATE_EVENT);
1073 BITMASK_CLEAR (&pThis->m_flags,
1074 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1075
1076 }
1077 }
1078
1079 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
1080 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001081 if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001082 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1083 pThis->omx_report_error ();
1084 break;
1085 }
1086 pThis->streaming[CAPTURE_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001087 if (!pThis->input_flush_progress)
1088 {
Vinay Kalia22046272012-09-28 20:16:05 -07001089 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
Shalaj Jain286b0062013-02-21 20:35:48 -08001090 pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
Vinay Kalia22046272012-09-28 20:16:05 -07001091 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001092 }
1093 }
1094 }
1095 }
1096 else
1097 {
1098 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1099 }
1100 }
1101 break;
1102
1103 case OMX_COMPONENT_GENERATE_START_DONE:
1104 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1105
1106 if (pThis->m_cb.EventHandler)
1107 {
1108 if (p2 != VDEC_S_SUCCESS)
1109 {
1110 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1111 pThis->omx_report_error ();
1112 }
1113 else
1114 {
1115 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1116 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1117 {
1118 DEBUG_PRINT_LOW("\n Move to executing");
1119 // Send the callback now
1120 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1121 pThis->m_state = OMX_StateExecuting;
1122 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1123 OMX_EventCmdComplete,OMX_CommandStateSet,
1124 OMX_StateExecuting, NULL);
1125 }
1126 else if (BITMASK_PRESENT(&pThis->m_flags,
1127 OMX_COMPONENT_PAUSE_PENDING))
1128 {
1129 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1130 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0)
1131 {
1132 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1133 pThis->omx_report_error ();
1134 }
1135 }
1136 }
1137 }
1138 else
1139 {
1140 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1141 }
1142 break;
1143
1144 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1145 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1146 if (pThis->m_cb.EventHandler)
1147 {
1148 if (p2 != VDEC_S_SUCCESS)
1149 {
1150 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1151 pThis->omx_report_error ();
1152 }
1153 else
1154 {
1155 pThis->complete_pending_buffer_done_cbs();
1156 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
1157 {
1158 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1159 //Send the callback now
1160 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1161 pThis->m_state = OMX_StatePause;
1162 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1163 OMX_EventCmdComplete,OMX_CommandStateSet,
1164 OMX_StatePause, NULL);
1165 }
1166 }
1167 }
1168 else
1169 {
1170 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1171 }
1172
1173 break;
1174
1175 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1176 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1177 if (pThis->m_cb.EventHandler)
1178 {
1179 if (p2 != VDEC_S_SUCCESS)
1180 {
1181 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1182 pThis->omx_report_error ();
1183 }
1184 else
1185 {
1186 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1187 {
1188 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1189 // Send the callback now
1190 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1191 pThis->m_state = OMX_StateExecuting;
1192 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1193 OMX_EventCmdComplete,OMX_CommandStateSet,
1194 OMX_StateExecuting,NULL);
1195 }
1196 }
1197 }
1198 else
1199 {
1200 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1201 }
1202
1203 break;
1204
1205 case OMX_COMPONENT_GENERATE_STOP_DONE:
1206 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1207 if (pThis->m_cb.EventHandler)
1208 {
1209 if (p2 != VDEC_S_SUCCESS)
1210 {
1211 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1212 pThis->omx_report_error ();
1213 }
1214 else
1215 {
1216 pThis->complete_pending_buffer_done_cbs();
1217 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
1218 {
1219 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1220 // Send the callback now
1221 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1222 pThis->m_state = OMX_StateIdle;
1223 DEBUG_PRINT_LOW("\n Move to Idle State");
1224 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1225 OMX_EventCmdComplete,OMX_CommandStateSet,
1226 OMX_StateIdle,NULL);
1227 }
1228 }
1229 }
1230 else
1231 {
1232 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1233 }
1234
1235 break;
1236
1237 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1238 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001239
Vinay Kalia592e4b42012-12-19 15:55:47 -08001240 if (p2 == OMX_IndexParamPortDefinition) {
1241 pThis->in_reconfig = true;
1242 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001243 if (pThis->m_cb.EventHandler) {
1244 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Vinay Kalia592e4b42012-12-19 15:55:47 -08001245 OMX_EventPortSettingsChanged, p1, p2, NULL );
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001246 } else {
1247 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1248 }
1249
1250 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
Shalaj Jain273b3e02012-06-22 19:08:03 -07001251 {
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001252 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
1253 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
1254 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
1255 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
1256 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
1257 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
1258 else //unsupported interlace format; raise a error
1259 event = OMX_EventError;
1260 if (pThis->m_cb.EventHandler) {
1261 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1262 event, format, 0, NULL );
1263 } else {
1264 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001265 }
1266 }
1267 break;
1268
1269 case OMX_COMPONENT_GENERATE_EOS_DONE:
1270 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1271 if (pThis->m_cb.EventHandler) {
1272 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1273 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1274 } else {
1275 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1276 }
1277 pThis->prev_ts = LLONG_MAX;
1278 pThis->rst_prev_ts = true;
1279 break;
1280
1281 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1282 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1283 pThis->omx_report_error ();
1284 break;
Arun Menon6836ba02013-02-19 20:37:40 -08001285
1286 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
1287 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
1288 pThis->omx_report_unsupported_setting();
1289 break;
1290
Shalaj Jain273b3e02012-06-22 19:08:03 -07001291 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG:
1292 {
1293 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
1294 if (pThis->m_cb.EventHandler) {
1295 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1296 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1297 } else {
1298 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1299 }
1300 }
1301 default:
1302 break;
1303 }
1304 }
1305 pthread_mutex_lock(&pThis->m_lock);
1306 qsize = pThis->m_cmd_q.m_size;
1307 if (pThis->m_state != OMX_StatePause)
1308 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1309 pthread_mutex_unlock(&pThis->m_lock);
1310 }
1311 while(qsize>0);
1312
1313}
1314
Vinay Kalia592e4b42012-12-19 15:55:47 -08001315void omx_vdec::update_resolution(int width, int height)
1316{
1317 drv_ctx.video_resolution.frame_height = height;
1318 drv_ctx.video_resolution.frame_width = width;
1319 drv_ctx.video_resolution.scan_lines = height;
1320 drv_ctx.video_resolution.stride = width;
1321 rectangle.nLeft = 0;
1322 rectangle.nTop = 0;
1323 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1324 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
1325}
1326
Arun Menon6836ba02013-02-19 20:37:40 -08001327OMX_ERRORTYPE omx_vdec::is_video_session_supported()
1328{
1329 if (drv_ctx.video_resolution.frame_width < m_decoder_capability.min_width ||
1330 drv_ctx.video_resolution.frame_width > m_decoder_capability.max_width ||
1331 drv_ctx.video_resolution.frame_height < m_decoder_capability.min_height ||
1332 drv_ctx.video_resolution.frame_height > m_decoder_capability.max_height) {
1333 DEBUG_PRINT_ERROR("\n Unsupported video resolution width = %u height = %u\n",
1334 drv_ctx.video_resolution.frame_width,
1335 drv_ctx.video_resolution.frame_height);
1336 DEBUG_PRINT_ERROR("\n supported range width - min(%u) max(%u\n",
1337 m_decoder_capability.min_width,
1338 m_decoder_capability.max_width);
1339 DEBUG_PRINT_ERROR("\n supported range height - min(%u) max(%u)\n",
1340 m_decoder_capability.min_height,
1341 m_decoder_capability.max_height);
1342 return OMX_ErrorUnsupportedSetting;
1343 }
1344 DEBUG_PRINT_HIGH("\n video session supported\n");
1345 return OMX_ErrorNone;
1346}
1347
Shalaj Jain273b3e02012-06-22 19:08:03 -07001348/* ======================================================================
1349FUNCTION
1350 omx_vdec::ComponentInit
1351
1352DESCRIPTION
1353 Initialize the component.
1354
1355PARAMETERS
1356 ctxt -- Context information related to the self.
1357 id -- Event identifier. This could be any of the following:
1358 1. Command completion event
1359 2. Buffer done callback event
1360 3. Frame done callback event
1361
1362RETURN VALUE
1363 None.
1364
1365========================================================================== */
1366OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1367{
1368
1369 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001370 struct v4l2_fmtdesc fdesc;
1371 struct v4l2_format fmt;
1372 struct v4l2_requestbuffers bufreq;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001373 struct v4l2_control control;
Arun Menon6836ba02013-02-19 20:37:40 -08001374 struct v4l2_frmsizeenum frmsize;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001375 unsigned int alignment = 0,buffer_size = 0;
1376 int fds[2];
1377 int r,ret=0;
1378 bool codec_ambiguous = false;
Shalaj Jain286b0062013-02-21 20:35:48 -08001379 OMX_STRING device_name = (OMX_STRING)"/dev/video32";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001380 if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){
1381 struct v4l2_control control;
1382 secure_mode = true;
1383 arbitrary_bytes = false;
Shalaj Jain286b0062013-02-21 20:35:48 -08001384 role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001385 }
1386
Shalaj Jain273b3e02012-06-22 19:08:03 -07001387 drv_ctx.video_driver_fd = open("/dev/video32", O_RDWR);
1388
1389 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d",
1390 drv_ctx.video_driver_fd, errno);
1391
1392 if(drv_ctx.video_driver_fd == 0){
1393 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1394 }
1395
1396 if(drv_ctx.video_driver_fd < 0)
1397 {
1398 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1399 return OMX_ErrorInsufficientResources;
1400 }
1401 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1402 drv_ctx.frame_rate.fps_denominator = 1;
1403
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001404 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1405 if(ret < 0) {
1406 close(drv_ctx.video_driver_fd);
1407 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1408 return OMX_ErrorInsufficientResources;
1409 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001410
1411#ifdef INPUT_BUFFER_LOG
1412 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
1413#endif
1414#ifdef OUTPUT_BUFFER_LOG
1415 outputBufferFile1 = fopen (outputfilename, "ab");
1416#endif
1417#ifdef OUTPUT_EXTRADATA_LOG
1418 outputExtradataFile = fopen (ouputextradatafilename, "ab");
1419#endif
1420
1421 // Copy the role information which provides the decoder kind
1422 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001423
Shalaj Jain273b3e02012-06-22 19:08:03 -07001424 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1425 OMX_MAX_STRINGNAME_SIZE))
1426 {
1427 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1428 OMX_MAX_STRINGNAME_SIZE);
1429 drv_ctx.timestamp_adjust = true;
1430 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1431 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
Praneeth Paladugu2a046832012-07-09 20:51:51 -07001432 output_capability=V4L2_PIX_FMT_MPEG4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001433 /*Initialize Start Code for MPEG4*/
1434 codec_type_parse = CODEC_TYPE_MPEG4;
1435 m_frame_parser.init_start_codes (codec_type_parse);
1436#ifdef INPUT_BUFFER_LOG
1437 strcat(inputfilename, "m4v");
1438#endif
1439 }
1440 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1441 OMX_MAX_STRINGNAME_SIZE))
1442 {
1443 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1444 OMX_MAX_STRINGNAME_SIZE);
1445 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
Sachin Shah933b7d42012-06-25 21:27:33 -07001446 output_capability = V4L2_PIX_FMT_MPEG2;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001447 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1448 /*Initialize Start Code for MPEG2*/
1449 codec_type_parse = CODEC_TYPE_MPEG2;
1450 m_frame_parser.init_start_codes (codec_type_parse);
1451#ifdef INPUT_BUFFER_LOG
1452 strcat(inputfilename, "mpg");
1453#endif
1454 }
1455 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1456 OMX_MAX_STRINGNAME_SIZE))
1457 {
1458 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1459 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1460 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1461 eCompressionFormat = OMX_VIDEO_CodingH263;
Deva Ramasubramanian0868a002012-06-20 23:04:30 -07001462 output_capability = V4L2_PIX_FMT_H263;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001463 codec_type_parse = CODEC_TYPE_H263;
1464 m_frame_parser.init_start_codes (codec_type_parse);
1465#ifdef INPUT_BUFFER_LOG
1466 strcat(inputfilename, "263");
1467#endif
1468 }
1469 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1470 OMX_MAX_STRINGNAME_SIZE))
1471 {
1472 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1473 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1474 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1475 output_capability = V4L2_PIX_FMT_DIVX_311;
1476 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1477 codec_type_parse = CODEC_TYPE_DIVX;
1478 m_frame_parser.init_start_codes (codec_type_parse);
1479
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001480 eRet = createDivxDrmContext();
1481 if (eRet != OMX_ErrorNone) {
1482 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1483 return eRet;
1484 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001485 }
1486 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1487 OMX_MAX_STRINGNAME_SIZE))
1488 {
1489 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1490 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1491 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1492 output_capability = V4L2_PIX_FMT_DIVX;
1493 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1494 codec_type_parse = CODEC_TYPE_DIVX;
1495 codec_ambiguous = true;
1496 m_frame_parser.init_start_codes (codec_type_parse);
1497
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001498 eRet = createDivxDrmContext();
1499 if (eRet != OMX_ErrorNone) {
1500 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1501 return eRet;
1502 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001503 }
1504 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1505 OMX_MAX_STRINGNAME_SIZE))
1506 {
1507 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1508 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1509 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1510 output_capability = V4L2_PIX_FMT_DIVX;
1511 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1512 codec_type_parse = CODEC_TYPE_DIVX;
1513 codec_ambiguous = true;
1514 m_frame_parser.init_start_codes (codec_type_parse);
1515
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001516 eRet = createDivxDrmContext();
1517 if (eRet != OMX_ErrorNone) {
1518 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1519 return eRet;
1520 }
1521
Shalaj Jain273b3e02012-06-22 19:08:03 -07001522 }
1523 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1524 OMX_MAX_STRINGNAME_SIZE))
1525 {
1526 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1527 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1528 output_capability=V4L2_PIX_FMT_H264;
1529 eCompressionFormat = OMX_VIDEO_CodingAVC;
1530 codec_type_parse = CODEC_TYPE_H264;
1531 m_frame_parser.init_start_codes (codec_type_parse);
1532 m_frame_parser.init_nal_length(nal_length);
1533#ifdef INPUT_BUFFER_LOG
1534 strcat(inputfilename, "264");
1535#endif
1536 }
1537 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1538 OMX_MAX_STRINGNAME_SIZE))
1539 {
1540 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1541 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1542 eCompressionFormat = OMX_VIDEO_CodingWMV;
1543 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugueed23ec2012-07-09 21:02:39 -07001544 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001545 m_frame_parser.init_start_codes (codec_type_parse);
1546#ifdef INPUT_BUFFER_LOG
1547 strcat(inputfilename, "vc1");
1548#endif
1549 }
1550 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1551 OMX_MAX_STRINGNAME_SIZE))
1552 {
1553 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1554 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1555 eCompressionFormat = OMX_VIDEO_CodingWMV;
1556 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07001557 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001558 m_frame_parser.init_start_codes (codec_type_parse);
1559#ifdef INPUT_BUFFER_LOG
1560 strcat(inputfilename, "vc1");
1561#endif
1562 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001563 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1564 OMX_MAX_STRINGNAME_SIZE))
1565 {
1566 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1567 output_capability=V4L2_PIX_FMT_VP8;
1568 eCompressionFormat = OMX_VIDEO_CodingVPX;
1569 codec_type_parse = CODEC_TYPE_VP8;
1570 arbitrary_bytes = false;
1571 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001572 else
1573 {
1574 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1575 eRet = OMX_ErrorInvalidComponentName;
1576 }
1577#ifdef INPUT_BUFFER_LOG
1578 inputBufferFile1 = fopen (inputfilename, "ab");
1579#endif
1580 if (eRet == OMX_ErrorNone)
1581 {
1582
Vinay Kaliada4f4422013-01-09 10:45:03 -08001583 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
1584 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1585 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1586 if (!client_buffers.set_color_format(dest_color_format)) {
1587 DEBUG_PRINT_ERROR("\n Setting color format failed");
1588 eRet = OMX_ErrorInsufficientResources;
1589 }
1590
Shalaj Jain273b3e02012-06-22 19:08:03 -07001591 capture_capability= V4L2_PIX_FMT_NV12;
Vinay Kalia85793762012-06-14 19:12:34 -07001592 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001593 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001594 DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n");
1595 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001596 }
1597
1598 struct v4l2_capability cap;
1599 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1600 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001601 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001602 /*TODO: How to handle this case */
1603 } else {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001604 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Shalaj Jain273b3e02012-06-22 19:08:03 -07001605 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1606 cap.bus_info, cap.version, cap.capabilities);
1607 }
1608 ret=0;
1609 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1610 fdesc.index=0;
1611 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001612 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001613 fdesc.pixelformat, fdesc.flags);
1614 fdesc.index++;
1615 }
1616 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1617 fdesc.index=0;
1618 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1619
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001620 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001621 fdesc.pixelformat, fdesc.flags);
1622 fdesc.index++;
1623 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001624 update_resolution(320, 240);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001625 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1626 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1627 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1628 fmt.fmt.pix_mp.pixelformat = output_capability;
1629 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1630 if (ret) {
1631 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001632 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001633 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001634 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001635 if (codec_ambiguous) {
1636 if (output_capability == V4L2_PIX_FMT_DIVX) {
1637 struct v4l2_control divx_ctrl;
1638
1639 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001640 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001641 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001642 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001643 } else {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001644 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001645 }
1646
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001647 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
Praneeth Paladuguf54dd1b2012-09-18 12:18:22 -07001648 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001649 if (ret) {
1650 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1651 }
1652 } else {
1653 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1654 }
1655 }
1656
Arun Menon6836ba02013-02-19 20:37:40 -08001657 //Get the hardware capabilities
1658 memset((void *)&frmsize,0,sizeof(frmsize));
1659 frmsize.index = 0;
1660 frmsize.pixel_format = output_capability;
1661 ret = ioctl(drv_ctx.video_driver_fd,
1662 VIDIOC_ENUM_FRAMESIZES, &frmsize);
1663 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
1664 DEBUG_PRINT_ERROR("Failed to get framesizes\n");
1665 return OMX_ErrorHardware;
1666 }
1667
1668 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
1669 m_decoder_capability.min_width = frmsize.stepwise.min_width;
1670 m_decoder_capability.max_width = frmsize.stepwise.max_width;
1671 m_decoder_capability.min_height = frmsize.stepwise.min_height;
1672 m_decoder_capability.max_height = frmsize.stepwise.max_height;
1673 }
1674
Shalaj Jain273b3e02012-06-22 19:08:03 -07001675 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1676 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1677 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07001678 fmt.fmt.pix_mp.pixelformat = capture_capability;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001679 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1680 if (ret) {
1681 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001682 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001683 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001684 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Vinay Kalia53fa6832012-10-11 17:55:30 -07001685 if(secure_mode){
Vinay Kalia53fa6832012-10-11 17:55:30 -07001686 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1687 control.value = 1;
1688 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1689 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1690 if (ret) {
1691 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1692 close(drv_ctx.video_driver_fd);
1693 return OMX_ErrorInsufficientResources;
1694 }
1695 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001696
1697 /*Get the Buffer requirements for input and output ports*/
1698 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1699 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
Vinay Kalia53fa6832012-10-11 17:55:30 -07001700 if (secure_mode) {
1701 drv_ctx.op_buf.alignment=SZ_1M;
1702 drv_ctx.ip_buf.alignment=SZ_1M;
1703 } else {
1704 drv_ctx.op_buf.alignment=SZ_4K;
1705 drv_ctx.ip_buf.alignment=SZ_4K;
1706 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001707 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1708 drv_ctx.extradata = 0;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001709 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1710 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1711 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1712 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001713 drv_ctx.idr_only_decoding = 0;
1714
Vinay Kalia5713bb32013-01-16 18:39:59 -08001715 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001716#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001717 if (eRet == OMX_ErrorNone && !secure_mode)
1718 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001719#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001720 eRet=get_buffer_req(&drv_ctx.ip_buf);
1721 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1722 get_buffer_req(&drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001723 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
1724 {
1725 if (m_frame_parser.mutils == NULL)
1726 {
1727 m_frame_parser.mutils = new H264_Utils();
1728
1729 if (m_frame_parser.mutils == NULL)
1730 {
1731 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1732 eRet = OMX_ErrorInsufficientResources;
1733 }
1734 else
1735 {
1736 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1737 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1738 h264_scratch.nFilledLen = 0;
1739 h264_scratch.nOffset = 0;
1740
1741 if (h264_scratch.pBuffer == NULL)
1742 {
1743 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1744 return OMX_ErrorInsufficientResources;
1745 }
1746 m_frame_parser.mutils->initialize_frame_checking_environment();
1747 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1748 }
1749 }
1750
1751 h264_parser = new h264_stream_parser();
1752 if (!h264_parser)
1753 {
1754 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1755 eRet = OMX_ErrorInsufficientResources;
1756 }
1757 }
1758
1759 if(pipe(fds))
1760 {
1761 DEBUG_PRINT_ERROR("pipe creation failed\n");
1762 eRet = OMX_ErrorInsufficientResources;
1763 }
1764 else
1765 {
1766 int temp1[2];
1767 if(fds[0] == 0 || fds[1] == 0)
1768 {
1769 if (pipe (temp1))
1770 {
1771 DEBUG_PRINT_ERROR("pipe creation failed\n");
1772 return OMX_ErrorInsufficientResources;
1773 }
1774 //close (fds[0]);
1775 //close (fds[1]);
1776 fds[0] = temp1 [0];
1777 fds[1] = temp1 [1];
1778 }
1779 m_pipe_in = fds[0];
1780 m_pipe_out = fds[1];
1781 r = pthread_create(&msg_thread_id,0,message_thread,this);
1782
1783 if(r < 0)
1784 {
1785 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1786 eRet = OMX_ErrorInsufficientResources;
1787 }
1788 }
1789 }
1790
1791 if (eRet != OMX_ErrorNone)
1792 {
1793 DEBUG_PRINT_ERROR("\n Component Init Failed");
1794 DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
1795 (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
1796 NULL);
1797 DEBUG_PRINT_HIGH("\n Calling close() on Video Driver");
1798 close (drv_ctx.video_driver_fd);
1799 drv_ctx.video_driver_fd = -1;
1800 }
1801 else
1802 {
1803 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1804 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001805 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1806 return eRet;
1807}
1808
1809/* ======================================================================
1810FUNCTION
1811 omx_vdec::GetComponentVersion
1812
1813DESCRIPTION
1814 Returns the component version.
1815
1816PARAMETERS
1817 TBD.
1818
1819RETURN VALUE
1820 OMX_ErrorNone.
1821
1822========================================================================== */
1823OMX_ERRORTYPE omx_vdec::get_component_version
1824 (
1825 OMX_IN OMX_HANDLETYPE hComp,
1826 OMX_OUT OMX_STRING componentName,
1827 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1828 OMX_OUT OMX_VERSIONTYPE* specVersion,
1829 OMX_OUT OMX_UUIDTYPE* componentUUID
1830 )
1831{
1832 if(m_state == OMX_StateInvalid)
1833 {
1834 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1835 return OMX_ErrorInvalidState;
1836 }
1837 /* TBD -- Return the proper version */
1838 if (specVersion)
1839 {
1840 specVersion->nVersion = OMX_SPEC_VERSION;
1841 }
1842 return OMX_ErrorNone;
1843}
1844/* ======================================================================
1845FUNCTION
1846 omx_vdec::SendCommand
1847
1848DESCRIPTION
1849 Returns zero if all the buffers released..
1850
1851PARAMETERS
1852 None.
1853
1854RETURN VALUE
1855 true/false
1856
1857========================================================================== */
1858OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
1859 OMX_IN OMX_COMMANDTYPE cmd,
1860 OMX_IN OMX_U32 param1,
1861 OMX_IN OMX_PTR cmdData
1862 )
1863{
1864 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1865 if(m_state == OMX_StateInvalid)
1866 {
1867 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1868 return OMX_ErrorInvalidState;
1869 }
1870 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
1871 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL)
1872 {
1873 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
Praneeth Paladugu32284302013-02-14 22:53:06 -08001874 "to invalid port: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001875 return OMX_ErrorBadPortIndex;
1876 }
1877 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1878 sem_wait(&m_cmd_lock);
1879 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1880 return OMX_ErrorNone;
1881}
1882
1883/* ======================================================================
1884FUNCTION
1885 omx_vdec::SendCommand
1886
1887DESCRIPTION
1888 Returns zero if all the buffers released..
1889
1890PARAMETERS
1891 None.
1892
1893RETURN VALUE
1894 true/false
1895
1896========================================================================== */
1897OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1898 OMX_IN OMX_COMMANDTYPE cmd,
1899 OMX_IN OMX_U32 param1,
1900 OMX_IN OMX_PTR cmdData
1901 )
1902{
1903 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1904 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1905 int bFlag = 1,sem_posted = 0,ret=0;
1906
1907 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1908 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1909 m_state, eState);
1910
1911 if(cmd == OMX_CommandStateSet)
1912 {
1913 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1914 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1915 /***************************/
1916 /* Current State is Loaded */
1917 /***************************/
1918 if(m_state == OMX_StateLoaded)
1919 {
1920 if(eState == OMX_StateIdle)
1921 {
1922 //if all buffers are allocated or all ports disabled
1923 if(allocate_done() ||
1924 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
1925 {
1926 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1927 }
1928 else
1929 {
1930 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1931 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1932 // Skip the event notification
1933 bFlag = 0;
1934 }
1935 }
1936 /* Requesting transition from Loaded to Loaded */
1937 else if(eState == OMX_StateLoaded)
1938 {
1939 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1940 post_event(OMX_EventError,OMX_ErrorSameState,\
1941 OMX_COMPONENT_GENERATE_EVENT);
1942 eRet = OMX_ErrorSameState;
1943 }
1944 /* Requesting transition from Loaded to WaitForResources */
1945 else if(eState == OMX_StateWaitForResources)
1946 {
1947 /* Since error is None , we will post an event
1948 at the end of this function definition */
1949 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1950 }
1951 /* Requesting transition from Loaded to Executing */
1952 else if(eState == OMX_StateExecuting)
1953 {
1954 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1955 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1956 OMX_COMPONENT_GENERATE_EVENT);
1957 eRet = OMX_ErrorIncorrectStateTransition;
1958 }
1959 /* Requesting transition from Loaded to Pause */
1960 else if(eState == OMX_StatePause)
1961 {
1962 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1963 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1964 OMX_COMPONENT_GENERATE_EVENT);
1965 eRet = OMX_ErrorIncorrectStateTransition;
1966 }
1967 /* Requesting transition from Loaded to Invalid */
1968 else if(eState == OMX_StateInvalid)
1969 {
1970 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1971 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1972 eRet = OMX_ErrorInvalidState;
1973 }
1974 else
1975 {
1976 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1977 eState);
1978 eRet = OMX_ErrorBadParameter;
1979 }
1980 }
1981
1982 /***************************/
1983 /* Current State is IDLE */
1984 /***************************/
1985 else if(m_state == OMX_StateIdle)
1986 {
1987 if(eState == OMX_StateLoaded)
1988 {
1989 if(release_done())
1990 {
1991 /*
1992 Since error is None , we will post an event at the end
1993 of this function definition
1994 */
1995 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
1996 }
1997 else
1998 {
1999 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
2000 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
2001 // Skip the event notification
2002 bFlag = 0;
2003 }
2004 }
2005 /* Requesting transition from Idle to Executing */
2006 else if(eState == OMX_StateExecuting)
2007 {
2008 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2009 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
2010 bFlag = 1;
2011 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2012 m_state=OMX_StateExecuting;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07002013 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07002014 }
2015 /* Requesting transition from Idle to Idle */
2016 else if(eState == OMX_StateIdle)
2017 {
2018 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
2019 post_event(OMX_EventError,OMX_ErrorSameState,\
2020 OMX_COMPONENT_GENERATE_EVENT);
2021 eRet = OMX_ErrorSameState;
2022 }
2023 /* Requesting transition from Idle to WaitForResources */
2024 else if(eState == OMX_StateWaitForResources)
2025 {
2026 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
2027 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2028 OMX_COMPONENT_GENERATE_EVENT);
2029 eRet = OMX_ErrorIncorrectStateTransition;
2030 }
2031 /* Requesting transition from Idle to Pause */
2032 else if(eState == OMX_StatePause)
2033 {
2034 /*To pause the Video core we need to start the driver*/
2035 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
2036 NULL) < */0)
2037 {
2038 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
2039 omx_report_error ();
2040 eRet = OMX_ErrorHardware;
2041 }
2042 else
2043 {
2044 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2045 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
2046 bFlag = 0;
2047 }
2048 }
2049 /* Requesting transition from Idle to Invalid */
2050 else if(eState == OMX_StateInvalid)
2051 {
2052 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
2053 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2054 eRet = OMX_ErrorInvalidState;
2055 }
2056 else
2057 {
2058 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
2059 eRet = OMX_ErrorBadParameter;
2060 }
2061 }
2062
2063 /******************************/
2064 /* Current State is Executing */
2065 /******************************/
2066 else if(m_state == OMX_StateExecuting)
2067 {
2068 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
2069 /* Requesting transition from Executing to Idle */
2070 if(eState == OMX_StateIdle)
Vinay Kalia85793762012-06-14 19:12:34 -07002071 {
2072 /* Since error is None , we will post an event
2073 at the end of this function definition
2074 */
2075 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002076 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
Vinay Kalia85793762012-06-14 19:12:34 -07002077 if(!sem_posted)
2078 {
2079 sem_posted = 1;
2080 sem_post (&m_cmd_lock);
2081 execute_omx_flush(OMX_ALL);
2082 }
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002083 bFlag = 0;
Vinay Kalia85793762012-06-14 19:12:34 -07002084 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002085 /* Requesting transition from Executing to Paused */
2086 else if(eState == OMX_StatePause)
2087 {
2088 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002089 m_state = OMX_StatePause;
2090 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002091 }
2092 /* Requesting transition from Executing to Loaded */
2093 else if(eState == OMX_StateLoaded)
2094 {
2095 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2096 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2097 OMX_COMPONENT_GENERATE_EVENT);
2098 eRet = OMX_ErrorIncorrectStateTransition;
2099 }
2100 /* Requesting transition from Executing to WaitForResources */
2101 else if(eState == OMX_StateWaitForResources)
2102 {
2103 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2104 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2105 OMX_COMPONENT_GENERATE_EVENT);
2106 eRet = OMX_ErrorIncorrectStateTransition;
2107 }
2108 /* Requesting transition from Executing to Executing */
2109 else if(eState == OMX_StateExecuting)
2110 {
2111 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2112 post_event(OMX_EventError,OMX_ErrorSameState,\
2113 OMX_COMPONENT_GENERATE_EVENT);
2114 eRet = OMX_ErrorSameState;
2115 }
2116 /* Requesting transition from Executing to Invalid */
2117 else if(eState == OMX_StateInvalid)
2118 {
2119 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2120 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2121 eRet = OMX_ErrorInvalidState;
2122 }
2123 else
2124 {
2125 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2126 eRet = OMX_ErrorBadParameter;
2127 }
2128 }
2129 /***************************/
2130 /* Current State is Pause */
2131 /***************************/
2132 else if(m_state == OMX_StatePause)
2133 {
2134 /* Requesting transition from Pause to Executing */
2135 if(eState == OMX_StateExecuting)
2136 {
2137 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
Praneeth Paladuguef06fe62013-03-11 12:38:40 -07002138 m_state = OMX_StateExecuting;
2139 bFlag = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002140 }
2141 /* Requesting transition from Pause to Idle */
2142 else if(eState == OMX_StateIdle)
2143 {
2144 /* Since error is None , we will post an event
2145 at the end of this function definition */
2146 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2147 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2148 if(!sem_posted)
2149 {
2150 sem_posted = 1;
2151 sem_post (&m_cmd_lock);
2152 execute_omx_flush(OMX_ALL);
2153 }
2154 bFlag = 0;
2155 }
2156 /* Requesting transition from Pause to loaded */
2157 else if(eState == OMX_StateLoaded)
2158 {
2159 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2160 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2161 OMX_COMPONENT_GENERATE_EVENT);
2162 eRet = OMX_ErrorIncorrectStateTransition;
2163 }
2164 /* Requesting transition from Pause to WaitForResources */
2165 else if(eState == OMX_StateWaitForResources)
2166 {
2167 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2168 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2169 OMX_COMPONENT_GENERATE_EVENT);
2170 eRet = OMX_ErrorIncorrectStateTransition;
2171 }
2172 /* Requesting transition from Pause to Pause */
2173 else if(eState == OMX_StatePause)
2174 {
2175 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2176 post_event(OMX_EventError,OMX_ErrorSameState,\
2177 OMX_COMPONENT_GENERATE_EVENT);
2178 eRet = OMX_ErrorSameState;
2179 }
2180 /* Requesting transition from Pause to Invalid */
2181 else if(eState == OMX_StateInvalid)
2182 {
2183 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2184 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2185 eRet = OMX_ErrorInvalidState;
2186 }
2187 else
2188 {
2189 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2190 eRet = OMX_ErrorBadParameter;
2191 }
2192 }
2193 /***************************/
2194 /* Current State is WaitForResources */
2195 /***************************/
2196 else if(m_state == OMX_StateWaitForResources)
2197 {
2198 /* Requesting transition from WaitForResources to Loaded */
2199 if(eState == OMX_StateLoaded)
2200 {
2201 /* Since error is None , we will post an event
2202 at the end of this function definition */
2203 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2204 }
2205 /* Requesting transition from WaitForResources to WaitForResources */
2206 else if (eState == OMX_StateWaitForResources)
2207 {
2208 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2209 post_event(OMX_EventError,OMX_ErrorSameState,
2210 OMX_COMPONENT_GENERATE_EVENT);
2211 eRet = OMX_ErrorSameState;
2212 }
2213 /* Requesting transition from WaitForResources to Executing */
2214 else if(eState == OMX_StateExecuting)
2215 {
2216 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2217 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2218 OMX_COMPONENT_GENERATE_EVENT);
2219 eRet = OMX_ErrorIncorrectStateTransition;
2220 }
2221 /* Requesting transition from WaitForResources to Pause */
2222 else if(eState == OMX_StatePause)
2223 {
2224 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2225 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2226 OMX_COMPONENT_GENERATE_EVENT);
2227 eRet = OMX_ErrorIncorrectStateTransition;
2228 }
2229 /* Requesting transition from WaitForResources to Invalid */
2230 else if(eState == OMX_StateInvalid)
2231 {
2232 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2233 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2234 eRet = OMX_ErrorInvalidState;
2235 }
2236 /* Requesting transition from WaitForResources to Loaded -
2237 is NOT tested by Khronos TS */
2238
2239 }
2240 else
2241 {
2242 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2243 eRet = OMX_ErrorBadParameter;
2244 }
2245 }
2246 /********************************/
2247 /* Current State is Invalid */
2248 /*******************************/
2249 else if(m_state == OMX_StateInvalid)
2250 {
2251 /* State Transition from Inavlid to any state */
2252 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
2253 || OMX_StateIdle || OMX_StateExecuting
2254 || OMX_StatePause || OMX_StateInvalid))
2255 {
2256 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2257 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2258 OMX_COMPONENT_GENERATE_EVENT);
2259 eRet = OMX_ErrorInvalidState;
2260 }
2261 }
2262 else if (cmd == OMX_CommandFlush)
2263 {
2264 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002265 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002266 if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2267 {
2268 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2269 }
2270 if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2271 {
2272 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2273 }
2274 if (!sem_posted){
2275 sem_posted = 1;
2276 DEBUG_PRINT_LOW("\n Set the Semaphore");
2277 sem_post (&m_cmd_lock);
2278 execute_omx_flush(param1);
2279 }
2280 bFlag = 0;
2281 }
2282 else if ( cmd == OMX_CommandPortEnable)
2283 {
2284 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002285 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002286 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2287 {
2288 m_inp_bEnabled = OMX_TRUE;
2289
2290 if( (m_state == OMX_StateLoaded &&
2291 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2292 || allocate_input_done())
2293 {
2294 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2295 OMX_COMPONENT_GENERATE_EVENT);
2296 }
2297 else
2298 {
2299 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2300 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2301 // Skip the event notification
2302 bFlag = 0;
2303 }
2304 }
2305 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2306 {
2307 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2308 m_out_bEnabled = OMX_TRUE;
2309
2310 if( (m_state == OMX_StateLoaded &&
2311 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2312 || (allocate_output_done()))
2313 {
2314 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2315 OMX_COMPONENT_GENERATE_EVENT);
2316
2317 }
2318 else
2319 {
2320 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2321 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2322 // Skip the event notification
2323 bFlag = 0;
2324 }
2325 }
2326 }
2327 else if (cmd == OMX_CommandPortDisable)
2328 {
2329 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
Praneeth Paladugu32284302013-02-14 22:53:06 -08002330 "with param1: %lu", param1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002331 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2332 {
2333 m_inp_bEnabled = OMX_FALSE;
2334 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2335 && release_input_done())
2336 {
2337 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2338 OMX_COMPONENT_GENERATE_EVENT);
2339 }
2340 else
2341 {
2342 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2343 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2344 {
2345 if(!sem_posted)
2346 {
2347 sem_posted = 1;
2348 sem_post (&m_cmd_lock);
2349 }
2350 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2351 }
2352
2353 // Skip the event notification
2354 bFlag = 0;
2355 }
2356 }
2357 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2358 {
2359 m_out_bEnabled = OMX_FALSE;
2360 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2361 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2362 && release_output_done())
2363 {
2364 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2365 OMX_COMPONENT_GENERATE_EVENT);
2366 }
2367 else
2368 {
2369 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2370 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2371 {
2372 if (!sem_posted)
2373 {
2374 sem_posted = 1;
2375 sem_post (&m_cmd_lock);
2376 }
2377 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2378 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2379 }
2380 // Skip the event notification
2381 bFlag = 0;
2382
2383 }
2384 }
2385 }
2386 else
2387 {
2388 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2389 eRet = OMX_ErrorNotImplemented;
2390 }
2391 if(eRet == OMX_ErrorNone && bFlag)
2392 {
2393 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2394 }
2395 if(!sem_posted)
2396 {
2397 sem_post(&m_cmd_lock);
2398 }
2399
2400 return eRet;
2401}
2402
2403/* ======================================================================
2404FUNCTION
2405 omx_vdec::ExecuteOmxFlush
2406
2407DESCRIPTION
2408 Executes the OMX flush.
2409
2410PARAMETERS
2411 flushtype - input flush(1)/output flush(0)/ both.
2412
2413RETURN VALUE
2414 true/false
2415
2416========================================================================== */
2417bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2418{
Shalaj Jain273b3e02012-06-22 19:08:03 -07002419 bool bRet = false;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002420 struct v4l2_plane plane;
Praneeth Paladugu32284302013-02-14 22:53:06 -08002421 struct v4l2_buffer v4l2_buf;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002422 struct v4l2_decoder_cmd dec;
2423 DEBUG_PRINT_LOW("in %s", __func__);
Praneeth Paladugu32284302013-02-14 22:53:06 -08002424 memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002425 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002426 switch (flushType)
2427 {
2428 case OMX_CORE_INPUT_PORT_INDEX:
2429 input_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002430 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002431 break;
2432 case OMX_CORE_OUTPUT_PORT_INDEX:
2433 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002434 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002435 break;
2436 default:
2437 input_flush_progress = true;
2438 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002439 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT |
2440 V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002441 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002442
2443 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002444 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002445 DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002446 bRet = false;
2447 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002448
Shalaj Jain273b3e02012-06-22 19:08:03 -07002449 return bRet;
2450}
2451/*=========================================================================
2452FUNCTION : execute_output_flush
2453
2454DESCRIPTION
2455 Executes the OMX flush at OUTPUT PORT.
2456
2457PARAMETERS
2458 None.
2459
2460RETURN VALUE
2461 true/false
2462==========================================================================*/
2463bool omx_vdec::execute_output_flush()
2464{
2465 unsigned p1 = 0; // Parameter - 1
2466 unsigned p2 = 0; // Parameter - 2
2467 unsigned ident = 0;
2468 bool bRet = true;
2469
2470 /*Generate FBD for all Buffers in the FTBq*/
2471 pthread_mutex_lock(&m_lock);
2472 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2473 while (m_ftb_q.m_size)
2474 {
2475 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2476 m_ftb_q.m_size,pending_output_buffers);
2477 m_ftb_q.pop_entry(&p1,&p2,&ident);
2478 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Vinay Kaliada4f4422013-01-09 10:45:03 -08002479 if(ident == m_fill_output_msg )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002480 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08002481 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002482 }
2483 else if (ident == OMX_COMPONENT_GENERATE_FBD)
2484 {
2485 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2486 }
2487 }
2488 pthread_mutex_unlock(&m_lock);
2489 output_flush_progress = false;
2490
2491 if (arbitrary_bytes)
2492 {
2493 prev_ts = LLONG_MAX;
2494 rst_prev_ts = true;
2495 }
2496 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2497 return bRet;
2498}
2499/*=========================================================================
2500FUNCTION : execute_input_flush
2501
2502DESCRIPTION
2503 Executes the OMX flush at INPUT PORT.
2504
2505PARAMETERS
2506 None.
2507
2508RETURN VALUE
2509 true/false
2510==========================================================================*/
2511bool omx_vdec::execute_input_flush()
2512{
2513 unsigned i =0;
2514 unsigned p1 = 0; // Parameter - 1
2515 unsigned p2 = 0; // Parameter - 2
2516 unsigned ident = 0;
2517 bool bRet = true;
2518
2519 /*Generate EBD for all Buffers in the ETBq*/
2520 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
2521
2522 pthread_mutex_lock(&m_lock);
2523 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2524 while (m_etb_q.m_size)
2525 {
2526 m_etb_q.pop_entry(&p1,&p2,&ident);
2527
2528 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2529 {
2530 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2531 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2532 }
2533 else if(ident == OMX_COMPONENT_GENERATE_ETB)
2534 {
2535 pending_input_buffers++;
2536 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2537 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2538 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2539 }
2540 else if (ident == OMX_COMPONENT_GENERATE_EBD)
2541 {
2542 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2543 (OMX_BUFFERHEADERTYPE *)p1);
2544 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2545 }
2546 }
2547 time_stamp_dts.flush_timestamp();
2548 /*Check if Heap Buffers are to be flushed*/
2549 if (arbitrary_bytes)
2550 {
2551 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2552 h264_scratch.nFilledLen = 0;
2553 nal_count = 0;
2554 look_ahead_nal = false;
2555 frame_count = 0;
2556 h264_last_au_ts = LLONG_MAX;
2557 h264_last_au_flags = 0;
2558 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2559 m_demux_entries = 0;
2560 DEBUG_PRINT_LOW("\n Initialize parser");
2561 if (m_frame_parser.mutils)
2562 {
2563 m_frame_parser.mutils->initialize_frame_checking_environment();
2564 }
2565
2566 while (m_input_pending_q.m_size)
2567 {
2568 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2569 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2570 }
2571
2572 if (psource_frame)
2573 {
2574 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2575 psource_frame = NULL;
2576 }
2577
2578 if (pdest_frame)
2579 {
2580 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08002581 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
2582 (unsigned int)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002583 pdest_frame = NULL;
2584 }
2585 m_frame_parser.flush();
2586 }
2587 pthread_mutex_unlock(&m_lock);
2588 input_flush_progress = false;
2589 if (!arbitrary_bytes)
2590 {
2591 prev_ts = LLONG_MAX;
2592 rst_prev_ts = true;
2593 }
2594#ifdef _ANDROID_
2595 if (m_debug_timestamp)
2596 {
2597 m_timestamp_list.reset_ts_list();
2598 }
2599#endif
2600 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2601 return bRet;
2602}
2603
2604
2605/* ======================================================================
2606FUNCTION
2607 omx_vdec::SendCommandEvent
2608
2609DESCRIPTION
2610 Send the event to decoder pipe. This is needed to generate the callbacks
2611 in decoder thread context.
2612
2613PARAMETERS
2614 None.
2615
2616RETURN VALUE
2617 true/false
2618
2619========================================================================== */
2620bool omx_vdec::post_event(unsigned int p1,
2621 unsigned int p2,
2622 unsigned int id)
2623{
2624 bool bRet = false;
2625
2626
2627 pthread_mutex_lock(&m_lock);
2628
Vinay Kaliada4f4422013-01-09 10:45:03 -08002629 if (id == m_fill_output_msg ||
Shalaj Jain273b3e02012-06-22 19:08:03 -07002630 id == OMX_COMPONENT_GENERATE_FBD)
2631 {
2632 m_ftb_q.insert_entry(p1,p2,id);
2633 }
2634 else if (id == OMX_COMPONENT_GENERATE_ETB ||
2635 id == OMX_COMPONENT_GENERATE_EBD ||
2636 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2637 {
2638 m_etb_q.insert_entry(p1,p2,id);
2639 }
2640 else
2641 {
2642 m_cmd_q.insert_entry(p1,p2,id);
2643 }
2644
2645 bRet = true;
2646 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2647 post_message(this, id);
2648
2649 pthread_mutex_unlock(&m_lock);
2650
2651 return bRet;
2652}
2653
2654OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2655{
Vinay Kaliada4f4422013-01-09 10:45:03 -08002656 OMX_ERRORTYPE eRet = OMX_ErrorNoMore;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002657 if(!profileLevelType)
2658 return OMX_ErrorBadParameter;
2659
2660 if(profileLevelType->nPortIndex == 0) {
2661 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2662 {
2663 if (profileLevelType->nProfileIndex == 0)
2664 {
2665 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2666 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2667
2668 }
2669 else if (profileLevelType->nProfileIndex == 1)
2670 {
2671 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2672 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2673 }
2674 else if(profileLevelType->nProfileIndex == 2)
2675 {
2676 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2677 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2678 }
2679 else
2680 {
2681 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
2682 profileLevelType->nProfileIndex);
2683 eRet = OMX_ErrorNoMore;
2684 }
2685 }
2686 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)))
2687 {
2688 if (profileLevelType->nProfileIndex == 0)
2689 {
2690 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2691 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2692 }
2693 else
2694 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002695 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002696 eRet = OMX_ErrorNoMore;
2697 }
2698 }
2699 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2700 {
2701 if (profileLevelType->nProfileIndex == 0)
2702 {
2703 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2704 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2705 }
2706 else if(profileLevelType->nProfileIndex == 1)
2707 {
2708 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2709 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2710 }
2711 else
2712 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002713 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002714 eRet = OMX_ErrorNoMore;
2715 }
2716 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07002717 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
2718 {
2719 eRet = OMX_ErrorNoMore;
2720 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002721 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
2722 {
2723 if (profileLevelType->nProfileIndex == 0)
2724 {
2725 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2726 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2727 }
2728 else if(profileLevelType->nProfileIndex == 1)
2729 {
2730 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2731 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2732 }
2733 else
2734 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002735 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002736 eRet = OMX_ErrorNoMore;
2737 }
2738 }
2739 }
2740 else
2741 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08002742 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002743 eRet = OMX_ErrorBadPortIndex;
2744 }
2745 return eRet;
2746}
2747
2748/* ======================================================================
2749FUNCTION
2750 omx_vdec::GetParameter
2751
2752DESCRIPTION
2753 OMX Get Parameter method implementation
2754
2755PARAMETERS
2756 <TBD>.
2757
2758RETURN VALUE
2759 Error None if successful.
2760
2761========================================================================== */
2762OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
2763 OMX_IN OMX_INDEXTYPE paramIndex,
2764 OMX_INOUT OMX_PTR paramData)
2765{
2766 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2767
2768 DEBUG_PRINT_LOW("get_parameter: \n");
2769 if(m_state == OMX_StateInvalid)
2770 {
2771 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2772 return OMX_ErrorInvalidState;
2773 }
2774 if(paramData == NULL)
2775 {
2776 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2777 return OMX_ErrorBadParameter;
2778 }
Shalaj Jain286b0062013-02-21 20:35:48 -08002779 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07002780 {
2781 case OMX_IndexParamPortDefinition:
2782 {
2783 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2784 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2785 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2786 eRet = update_portdef(portDefn);
2787 if (eRet == OMX_ErrorNone)
2788 m_port_def = *portDefn;
2789 break;
2790 }
2791 case OMX_IndexParamVideoInit:
2792 {
2793 OMX_PORT_PARAM_TYPE *portParamType =
2794 (OMX_PORT_PARAM_TYPE *) paramData;
2795 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2796
2797 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2798 portParamType->nSize = sizeof(portParamType);
2799 portParamType->nPorts = 2;
2800 portParamType->nStartPortNumber = 0;
2801 break;
2802 }
2803 case OMX_IndexParamVideoPortFormat:
2804 {
2805 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2806 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2807 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2808
2809 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2810 portFmt->nSize = sizeof(portFmt);
2811
2812 if (0 == portFmt->nPortIndex)
2813 {
2814 if (0 == portFmt->nIndex)
2815 {
2816 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2817 portFmt->eCompressionFormat = eCompressionFormat;
2818 }
2819 else
2820 {
2821 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2822 " NoMore compression formats\n");
2823 eRet = OMX_ErrorNoMore;
2824 }
2825 }
2826 else if (1 == portFmt->nPortIndex)
2827 {
2828 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
2829
2830 if(0 == portFmt->nIndex)
Vinay Kaliada4f4422013-01-09 10:45:03 -08002831 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2832 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2833 else if (1 == portFmt->nIndex)
2834 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002835 else
2836 {
2837 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2838 " NoMore Color formats\n");
2839 eRet = OMX_ErrorNoMore;
2840 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002841 ALOGE("returning %d\n", portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002842 }
2843 else
2844 {
2845 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2846 (int)portFmt->nPortIndex);
2847 eRet = OMX_ErrorBadPortIndex;
2848 }
2849 break;
2850 }
2851 /*Component should support this port definition*/
2852 case OMX_IndexParamAudioInit:
2853 {
2854 OMX_PORT_PARAM_TYPE *audioPortParamType =
2855 (OMX_PORT_PARAM_TYPE *) paramData;
2856 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2857 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2858 audioPortParamType->nSize = sizeof(audioPortParamType);
2859 audioPortParamType->nPorts = 0;
2860 audioPortParamType->nStartPortNumber = 0;
2861 break;
2862 }
2863 /*Component should support this port definition*/
2864 case OMX_IndexParamImageInit:
2865 {
2866 OMX_PORT_PARAM_TYPE *imagePortParamType =
2867 (OMX_PORT_PARAM_TYPE *) paramData;
2868 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2869 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2870 imagePortParamType->nSize = sizeof(imagePortParamType);
2871 imagePortParamType->nPorts = 0;
2872 imagePortParamType->nStartPortNumber = 0;
2873 break;
2874
2875 }
2876 /*Component should support this port definition*/
2877 case OMX_IndexParamOtherInit:
2878 {
2879 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2880 paramIndex);
2881 eRet =OMX_ErrorUnsupportedIndex;
2882 break;
2883 }
2884 case OMX_IndexParamStandardComponentRole:
2885 {
2886 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2887 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2888 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2889 comp_role->nSize = sizeof(*comp_role);
2890
2891 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2892 paramIndex);
2893 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2894 OMX_MAX_STRINGNAME_SIZE);
2895 break;
2896 }
2897 /* Added for parameter test */
2898 case OMX_IndexParamPriorityMgmt:
2899 {
2900
2901 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2902 (OMX_PRIORITYMGMTTYPE *) paramData;
2903 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2904 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2905 priorityMgmType->nSize = sizeof(priorityMgmType);
2906
2907 break;
2908 }
2909 /* Added for parameter test */
2910 case OMX_IndexParamCompBufferSupplier:
2911 {
2912 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2913 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2914 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2915
2916 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2917 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2918 if(0 == bufferSupplierType->nPortIndex)
2919 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2920 else if (1 == bufferSupplierType->nPortIndex)
2921 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2922 else
2923 eRet = OMX_ErrorBadPortIndex;
2924
2925
2926 break;
2927 }
2928 case OMX_IndexParamVideoAvc:
2929 {
2930 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2931 paramIndex);
2932 break;
2933 }
2934 case OMX_IndexParamVideoH263:
2935 {
2936 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2937 paramIndex);
2938 break;
2939 }
2940 case OMX_IndexParamVideoMpeg4:
2941 {
2942 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2943 paramIndex);
2944 break;
2945 }
2946 case OMX_IndexParamVideoMpeg2:
2947 {
2948 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2949 paramIndex);
2950 break;
2951 }
2952 case OMX_IndexParamVideoProfileLevelQuerySupported:
2953 {
2954 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2955 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2956 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2957 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2958 break;
2959 }
2960#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2961 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
2962 {
2963 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2964 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2965 if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
2966
2967 if(secure_mode) {
2968 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
Riaz Rahaman4c3f67e2012-12-26 12:12:25 +05302969 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002970 } else {
Shalaj Jain5af07fb2013-03-07 11:38:41 -08002971 nativeBuffersUsage->nUsage =
2972 (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
2973 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002974 }
2975 } else {
2976 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
2977 eRet = OMX_ErrorBadParameter;
2978 }
2979 }
2980 break;
2981#endif
2982
2983 default:
2984 {
2985 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2986 eRet =OMX_ErrorUnsupportedIndex;
2987 }
2988
2989 }
2990
2991 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
2992 drv_ctx.video_resolution.frame_width,
2993 drv_ctx.video_resolution.frame_height,
2994 drv_ctx.video_resolution.stride,
2995 drv_ctx.video_resolution.scan_lines);
2996
2997 return eRet;
2998}
2999
3000#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3001OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
3002{
3003 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
3004 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3005 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
3006
3007 if((params == NULL) ||
3008 (params->nativeBuffer == NULL) ||
3009 (params->nativeBuffer->handle == NULL) ||
3010 !m_enable_android_native_buffers)
3011 return OMX_ErrorBadParameter;
3012 m_use_android_native_buffers = OMX_TRUE;
3013 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3014 private_handle_t *handle = (private_handle_t *)nBuf->handle;
3015 if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
3016 OMX_U8 *buffer = NULL;
3017 if(!secure_mode) {
3018 buffer = (OMX_U8*)mmap(0, handle->size,
3019 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3020 if(buffer == MAP_FAILED) {
3021 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3022 return OMX_ErrorInsufficientResources;
3023 }
3024 }
3025 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3026 } else {
3027 eRet = OMX_ErrorBadParameter;
3028 }
3029 return eRet;
3030}
3031#endif
3032/* ======================================================================
3033FUNCTION
3034 omx_vdec::Setparameter
3035
3036DESCRIPTION
3037 OMX Set Parameter method implementation.
3038
3039PARAMETERS
3040 <TBD>.
3041
3042RETURN VALUE
3043 OMX Error None if successful.
3044
3045========================================================================== */
3046OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
3047 OMX_IN OMX_INDEXTYPE paramIndex,
3048 OMX_IN OMX_PTR paramData)
3049{
3050 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003051 int ret=0;
3052 struct v4l2_format fmt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003053 if(m_state == OMX_StateInvalid)
3054 {
3055 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
3056 return OMX_ErrorInvalidState;
3057 }
3058 if(paramData == NULL)
3059 {
3060 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
3061 return OMX_ErrorBadParameter;
3062 }
3063 if((m_state != OMX_StateLoaded) &&
3064 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3065 (m_out_bEnabled == OMX_TRUE) &&
3066 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3067 (m_inp_bEnabled == OMX_TRUE)) {
3068 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
3069 return OMX_ErrorIncorrectStateOperation;
3070 }
Shalaj Jain286b0062013-02-21 20:35:48 -08003071 switch((unsigned long)paramIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003072 {
3073 case OMX_IndexParamPortDefinition:
3074 {
3075 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3076 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3077 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3078 //been called.
3079 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
3080 (int)portDefn->format.video.nFrameHeight,
3081 (int)portDefn->format.video.nFrameWidth);
3082 if(OMX_DirOutput == portDefn->eDir)
3083 {
3084 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
3085 m_display_id = portDefn->format.video.pNativeWindow;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003086 unsigned int buffer_size;
3087 if (!client_buffers.get_buffer_req(buffer_size)) {
3088 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003089 eRet = OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003090 } else {
3091 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3092 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size )
3093 {
3094 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3095 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3096 eRet = set_buffer_req(&drv_ctx.op_buf);
3097 if (eRet == OMX_ErrorNone)
3098 m_port_def = *portDefn;
3099 }
3100 else
3101 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003102 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Vinay Kaliada4f4422013-01-09 10:45:03 -08003103 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3104 portDefn->nBufferCountActual, portDefn->nBufferSize);
3105 eRet = OMX_ErrorBadParameter;
3106 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003107 }
3108 }
3109 else if(OMX_DirInput == portDefn->eDir)
3110 {
3111 if((portDefn->format.video.xFramerate >> 16) > 0 &&
3112 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS)
3113 {
3114 // Frame rate only should be set if this is a "known value" or to
3115 // activate ts prediction logic (arbitrary mode only) sending input
3116 // timestamps with max value (LLONG_MAX).
Praneeth Paladugu32284302013-02-14 22:53:06 -08003117 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003118 portDefn->format.video.xFramerate >> 16);
3119 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3120 drv_ctx.frame_rate.fps_denominator);
3121 if(!drv_ctx.frame_rate.fps_numerator)
3122 {
3123 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3124 drv_ctx.frame_rate.fps_numerator = 30;
3125 }
3126 if(drv_ctx.frame_rate.fps_denominator)
3127 drv_ctx.frame_rate.fps_numerator = (int)
3128 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3129 drv_ctx.frame_rate.fps_denominator = 1;
3130 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3131 drv_ctx.frame_rate.fps_numerator;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003132 DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
3133 frm_int, drv_ctx.frame_rate.fps_numerator /
3134 (float)drv_ctx.frame_rate.fps_denominator);
3135 }
3136 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
3137 if(drv_ctx.video_resolution.frame_height !=
3138 portDefn->format.video.nFrameHeight ||
3139 drv_ctx.video_resolution.frame_width !=
3140 portDefn->format.video.nFrameWidth)
3141 {
3142 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%d x %d)\n",
3143 portDefn->format.video.nFrameWidth,
3144 portDefn->format.video.nFrameHeight);
3145 if (portDefn->format.video.nFrameHeight != 0x0 &&
3146 portDefn->format.video.nFrameWidth != 0x0)
3147 {
Vinay Kalia592e4b42012-12-19 15:55:47 -08003148 update_resolution(portDefn->format.video.nFrameWidth,
3149 portDefn->format.video.nFrameHeight);
Arun Menon6836ba02013-02-19 20:37:40 -08003150 eRet = is_video_session_supported();
3151 if (eRet)
3152 break;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003153 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3154 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3155 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3156 fmt.fmt.pix_mp.pixelformat = output_capability;
3157 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);
3158 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
Praneeth Paladugu32284302013-02-14 22:53:06 -08003159 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003160 {
3161 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3162 eRet = OMX_ErrorUnsupportedSetting;
3163 }
3164 else
3165 eRet = get_buffer_req(&drv_ctx.op_buf);
3166 }
3167 }
3168 else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003169 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003170 {
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003171 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003172 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003173 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3174 (~(buffer_prop->alignment - 1));
3175 eRet = set_buffer_req(buffer_prop);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003176 }
3177 else
3178 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08003179 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003180 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3181 portDefn->nBufferCountActual, portDefn->nBufferSize);
3182 eRet = OMX_ErrorBadParameter;
3183 }
3184 }
3185 else if (portDefn->eDir == OMX_DirMax)
3186 {
3187 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3188 (int)portDefn->nPortIndex);
3189 eRet = OMX_ErrorBadPortIndex;
3190 }
3191 }
3192 break;
3193 case OMX_IndexParamVideoPortFormat:
3194 {
3195 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3196 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3197 int ret=0;
3198 struct v4l2_format fmt;
3199 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3200 portFmt->eColorFormat);
3201
3202 if(1 == portFmt->nPortIndex)
3203 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08003204 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3205 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3206 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3207 fmt.fmt.pix_mp.pixelformat = capture_capability;
3208 enum vdec_output_fromat op_format;
Shalaj Jain286b0062013-02-21 20:35:48 -08003209 if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
3210 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
Vinay Kaliada4f4422013-01-09 10:45:03 -08003211 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
Shalaj Jain286b0062013-02-21 20:35:48 -08003212 op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003213 else if(portFmt->eColorFormat ==
Shalaj Jain286b0062013-02-21 20:35:48 -08003214 (OMX_COLOR_FORMATTYPE)
Vinay Kaliada4f4422013-01-09 10:45:03 -08003215 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3216 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3217 else
3218 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003219
Vinay Kaliada4f4422013-01-09 10:45:03 -08003220 if(eRet == OMX_ErrorNone)
3221 {
3222 drv_ctx.output_format = op_format;
3223 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3224 if(ret)
3225 {
3226 DEBUG_PRINT_ERROR("\n Set output format failed");
3227 eRet = OMX_ErrorUnsupportedSetting;
3228 /*TODO: How to handle this case */
3229 }
3230 else
3231 {
3232 eRet = get_buffer_req(&drv_ctx.op_buf);
3233 }
3234 }
3235 if (eRet == OMX_ErrorNone){
3236 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3237 DEBUG_PRINT_ERROR("\n Set color format failed");
3238 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003239 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08003240 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003241 }
3242 }
3243 break;
3244
3245 case OMX_QcomIndexPortDefn:
3246 {
3247 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3248 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
3249 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d\n",
3250 portFmt->nFramePackingFormat);
3251
3252 /* Input port */
3253 if (portFmt->nPortIndex == 0)
3254 {
3255 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
3256 {
3257 if(secure_mode) {
3258 arbitrary_bytes = false;
3259 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3260 eRet = OMX_ErrorUnsupportedSetting;
3261 } else {
3262 arbitrary_bytes = true;
3263 }
3264 }
3265 else if (portFmt->nFramePackingFormat ==
3266 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
3267 {
3268 arbitrary_bytes = false;
3269 }
3270 else
3271 {
Shalaj Jain286b0062013-02-21 20:35:48 -08003272 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07003273 portFmt->nFramePackingFormat);
3274 eRet = OMX_ErrorUnsupportedSetting;
3275 }
3276 }
3277 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)
3278 {
3279 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3280 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3281 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3282 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone)
3283 {
3284 m_out_mem_region_smi = OMX_TRUE;
3285 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3286 {
3287 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3288 m_use_output_pmem = OMX_TRUE;
3289 }
3290 }
3291 }
3292 }
3293 break;
3294
3295 case OMX_IndexParamStandardComponentRole:
3296 {
3297 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3298 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3299 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3300 comp_role->cRole);
3301
3302 if((m_state == OMX_StateLoaded)&&
3303 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3304 {
3305 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3306 }
3307 else
3308 {
3309 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3310 return OMX_ErrorIncorrectStateOperation;
3311 }
3312
3313 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3314 {
3315 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3316 {
3317 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3318 }
3319 else
3320 {
3321 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3322 eRet =OMX_ErrorUnsupportedSetting;
3323 }
3324 }
3325 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3326 {
3327 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3328 {
3329 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3330 }
3331 else
3332 {
3333 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3334 eRet = OMX_ErrorUnsupportedSetting;
3335 }
3336 }
3337 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3338 {
3339 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3340 {
3341 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3342 }
3343 else
3344 {
3345 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3346 eRet =OMX_ErrorUnsupportedSetting;
3347 }
3348 }
3349 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3350 {
3351 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3352 {
3353 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3354 }
3355 else
3356 {
3357 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3358 eRet = OMX_ErrorUnsupportedSetting;
3359 }
3360 }
3361 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3362 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3363 )
3364 {
3365 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3366 {
3367 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3368 }
3369 else
3370 {
3371 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3372 eRet =OMX_ErrorUnsupportedSetting;
3373 }
3374 }
3375 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3376 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3377 )
3378 {
3379 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3380 {
3381 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3382 }
3383 else
3384 {
3385 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3386 eRet =OMX_ErrorUnsupportedSetting;
3387 }
3388 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003389 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3390 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003391 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3392 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE)))
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003393 {
3394 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3395 }
3396 else
3397 {
3398 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3399 eRet = OMX_ErrorUnsupportedSetting;
3400 }
3401 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003402 else
3403 {
3404 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3405 eRet = OMX_ErrorInvalidComponentName;
3406 }
3407 break;
3408 }
3409
3410 case OMX_IndexParamPriorityMgmt:
3411 {
3412 if(m_state != OMX_StateLoaded)
3413 {
3414 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3415 return OMX_ErrorIncorrectStateOperation;
3416 }
3417 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
3418 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n",
3419 priorityMgmtype->nGroupID);
3420
3421 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n",
3422 priorityMgmtype->nGroupPriority);
3423
3424 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3425 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3426
3427 break;
3428 }
3429
3430 case OMX_IndexParamCompBufferSupplier:
3431 {
3432 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3433 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3434 bufferSupplierType->eBufferSupplier);
3435 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3436 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3437
3438 else
3439
3440 eRet = OMX_ErrorBadPortIndex;
3441
3442 break;
3443
3444 }
3445 case OMX_IndexParamVideoAvc:
3446 {
3447 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3448 paramIndex);
3449 break;
3450 }
3451 case OMX_IndexParamVideoH263:
3452 {
3453 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3454 paramIndex);
3455 break;
3456 }
3457 case OMX_IndexParamVideoMpeg4:
3458 {
3459 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3460 paramIndex);
3461 break;
3462 }
3463 case OMX_IndexParamVideoMpeg2:
3464 {
3465 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3466 paramIndex);
3467 break;
3468 }
3469 case OMX_QcomIndexParamVideoDecoderPictureOrder:
3470 {
3471 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3472 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003473 struct v4l2_control control;
3474 int pic_order,rc=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003475 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3476 pictureOrder->eOutputPictureOrder);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003477 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3478 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3479 }
3480 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){
3481 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003482 time_stamp_dts.set_timestamp_reorder_mode(false);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003483 }
3484 else
3485 eRet = OMX_ErrorBadParameter;
3486 if (eRet == OMX_ErrorNone)
3487 {
3488 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3489 control.value = pic_order;
3490 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3491 if(rc)
3492 {
3493 DEBUG_PRINT_ERROR("\n Set picture order failed");
3494 eRet = OMX_ErrorUnsupportedSetting;
3495 }
3496 }
3497 break;
3498 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003499 case OMX_QcomIndexParamConcealMBMapExtraData:
3500 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003501 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003502 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3503 else {
3504 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3505 eRet = OMX_ErrorUnsupportedSetting;
3506 }
3507 break;
3508 case OMX_QcomIndexParamFrameInfoExtraData:
3509 {
3510 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003511 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003512 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3513 else {
3514 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3515 eRet = OMX_ErrorUnsupportedSetting;
3516 }
3517 break;
3518 }
3519 case OMX_QcomIndexParamInterlaceExtraData:
3520 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003521 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003522 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3523 else {
3524 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3525 eRet = OMX_ErrorUnsupportedSetting;
3526 }
3527 break;
3528 case OMX_QcomIndexParamH264TimeInfo:
3529 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003530 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003531 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3532 else {
3533 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3534 eRet = OMX_ErrorUnsupportedSetting;
3535 }
3536 break;
3537 case OMX_QcomIndexParamVideoDivx:
3538 {
3539 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003540 }
3541 break;
3542 case OMX_QcomIndexPlatformPvt:
3543 {
3544 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3545 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3546 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM)
3547 {
3548 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3549 eRet = OMX_ErrorUnsupportedSetting;
3550 }
3551 else
3552 {
3553 m_out_pvt_entry_pmem = OMX_TRUE;
3554 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3555 {
3556 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3557 m_use_output_pmem = OMX_TRUE;
3558 }
3559 }
3560
3561 }
3562 break;
3563 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3564 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003565 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3566 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3567 struct v4l2_control control;
3568 int rc;
3569 drv_ctx.idr_only_decoding = 1;
3570 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3571 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3572 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3573 if(rc)
3574 {
3575 DEBUG_PRINT_ERROR("\n Set picture order failed");
3576 eRet = OMX_ErrorUnsupportedSetting;
3577 } else {
3578 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3579 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3580 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3581 if(rc)
3582 {
3583 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3584 eRet = OMX_ErrorUnsupportedSetting;
3585 }
3586 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003587 }
3588 break;
3589
3590 case OMX_QcomIndexParamIndexExtraDataType:
3591 {
3592 if(!secure_mode) {
3593 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3594 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3595 (extradataIndexType->bEnabled == OMX_TRUE) &&
3596 (extradataIndexType->nPortIndex == 1))
3597 {
3598 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003599 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003600
Shalaj Jain273b3e02012-06-22 19:08:03 -07003601 }
3602 }
3603 }
3604 break;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003605 case OMX_QcomIndexParamEnableSmoothStreaming:
3606 {
3607 struct v4l2_control control;
3608 struct v4l2_format fmt;
3609 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3610 control.value = 1;
3611 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3612 if(rc < 0) {
3613 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3614 eRet = OMX_ErrorHardware;
3615 }
3616 }
3617 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003618#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3619 /* Need to allow following two set_parameters even in Idle
3620 * state. This is ANDROID architecture which is not in sync
3621 * with openmax standard. */
3622 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3623 {
3624 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3625 if(enableNativeBuffers) {
3626 m_enable_android_native_buffers = enableNativeBuffers->enable;
3627 }
3628 }
3629 break;
3630 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3631 {
3632 eRet = use_android_native_buffer(hComp, paramData);
3633 }
3634 break;
3635#endif
3636 case OMX_QcomIndexParamEnableTimeStampReorder:
3637 {
3638 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
Shalaj Jain286b0062013-02-21 20:35:48 -08003639 if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003640 if (reorder->bEnable == OMX_TRUE) {
3641 frm_int =0;
3642 time_stamp_dts.set_timestamp_reorder_mode(true);
3643 }
3644 else
3645 time_stamp_dts.set_timestamp_reorder_mode(false);
3646 } else {
3647 time_stamp_dts.set_timestamp_reorder_mode(false);
3648 if (reorder->bEnable == OMX_TRUE)
3649 {
3650 eRet = OMX_ErrorUnsupportedSetting;
3651 }
3652 }
3653 }
3654 break;
3655 default:
3656 {
3657 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3658 eRet = OMX_ErrorUnsupportedIndex;
3659 }
3660 }
3661 return eRet;
3662}
3663
3664/* ======================================================================
3665FUNCTION
3666 omx_vdec::GetConfig
3667
3668DESCRIPTION
3669 OMX Get Config Method implementation.
3670
3671PARAMETERS
3672 <TBD>.
3673
3674RETURN VALUE
3675 OMX Error None if successful.
3676
3677========================================================================== */
3678OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
3679 OMX_IN OMX_INDEXTYPE configIndex,
3680 OMX_INOUT OMX_PTR configData)
3681{
3682 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3683
3684 if (m_state == OMX_StateInvalid)
3685 {
3686 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3687 return OMX_ErrorInvalidState;
3688 }
3689
Shalaj Jain286b0062013-02-21 20:35:48 -08003690 switch ((unsigned long)configIndex)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003691 {
3692 case OMX_QcomIndexConfigInterlaced:
3693 {
3694 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3695 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3696 if (configFmt->nPortIndex == 1)
3697 {
3698 if (configFmt->nIndex == 0)
3699 {
3700 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3701 }
3702 else if (configFmt->nIndex == 1)
3703 {
3704 configFmt->eInterlaceType =
3705 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3706 }
3707 else if (configFmt->nIndex == 2)
3708 {
3709 configFmt->eInterlaceType =
3710 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3711 }
3712 else
3713 {
3714 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3715 " NoMore Interlaced formats\n");
3716 eRet = OMX_ErrorNoMore;
3717 }
3718
3719 }
3720 else
3721 {
3722 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3723 (int)configFmt->nPortIndex);
3724 eRet = OMX_ErrorBadPortIndex;
3725 }
3726 break;
3727 }
3728 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3729 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07003730 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3731 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003732 decoderinstances->nNumOfInstances = 16;
3733 /*TODO: How to handle this case */
3734 break;
3735 }
3736 case OMX_QcomIndexConfigVideoFramePackingArrangement:
3737 {
3738 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
3739 {
3740 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3741 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3742 h264_parser->get_frame_pack_data(configFmt);
3743 }
3744 else
3745 {
3746 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3747 }
3748 break;
3749 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08003750 case OMX_IndexConfigCommonOutputCrop:
3751 {
3752 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3753 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3754 break;
3755 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003756 default:
3757 {
3758 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3759 eRet = OMX_ErrorBadParameter;
3760 }
3761
3762 }
3763
3764 return eRet;
3765}
3766
3767/* ======================================================================
3768FUNCTION
3769 omx_vdec::SetConfig
3770
3771DESCRIPTION
3772 OMX Set Config method implementation
3773
3774PARAMETERS
3775 <TBD>.
3776
3777RETURN VALUE
3778 OMX Error None if successful.
3779========================================================================== */
3780OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3781 OMX_IN OMX_INDEXTYPE configIndex,
3782 OMX_IN OMX_PTR configData)
3783{
3784 if(m_state == OMX_StateInvalid)
3785 {
3786 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3787 return OMX_ErrorInvalidState;
3788 }
3789
3790 OMX_ERRORTYPE ret = OMX_ErrorNone;
3791 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3792
3793 DEBUG_PRINT_LOW("\n Set Config Called");
3794
3795 if (m_state == OMX_StateExecuting)
3796 {
3797 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
3798 return ret;
3799 }
3800
Shalaj Jain286b0062013-02-21 20:35:48 -08003801 if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003802 {
3803 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3804 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3805 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc"))
3806 {
3807 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3808 OMX_U32 extra_size;
3809 // Parsing done here for the AVC atom is definitely not generic
3810 // Currently this piece of code is working, but certainly
3811 // not tested with all .mp4 files.
3812 // Incase of failure, we might need to revisit this
3813 // for a generic piece of code.
3814
3815 // Retrieve size of NAL length field
3816 // byte #4 contains the size of NAL lenght field
3817 nal_length = (config->pData[4] & 0x03) + 1;
3818
3819 extra_size = 0;
3820 if (nal_length > 2)
3821 {
3822 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3823 extra_size = (nal_length - 2) * 2;
3824 }
3825
3826 // SPS starts from byte #6
3827 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3828 OMX_U8 *pDestBuf;
3829 m_vendor_config.nPortIndex = config->nPortIndex;
3830
3831 // minus 6 --> SPS starts from byte #6
3832 // minus 1 --> picture param set byte to be ignored from avcatom
3833 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3834 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3835 OMX_U32 len;
3836 OMX_U8 index = 0;
3837 // case where SPS+PPS is sent as part of set_config
3838 pDestBuf = m_vendor_config.pData;
3839
3840 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]\n",
3841 m_vendor_config.nPortIndex,
3842 m_vendor_config.nDataSize,
3843 m_vendor_config.pData);
3844 while (index < 2)
3845 {
3846 uint8 *psize;
3847 len = *pSrcBuf;
3848 len = len << 8;
3849 len |= *(pSrcBuf + 1);
3850 psize = (uint8 *) & len;
3851 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
Shalaj Jain286b0062013-02-21 20:35:48 -08003852 for (unsigned int i = 0; i < nal_length; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003853 {
3854 pDestBuf[i] = psize[nal_length - 1 - i];
3855 }
3856 //memcpy(pDestBuf,pSrcBuf,(len+2));
3857 pDestBuf += len + nal_length;
3858 pSrcBuf += len + 2;
3859 index++;
3860 pSrcBuf++; // skip picture param set
3861 len = 0;
3862 }
3863 }
3864 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3865 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2"))
3866 {
3867 m_vendor_config.nPortIndex = config->nPortIndex;
3868 m_vendor_config.nDataSize = config->nDataSize;
3869 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3870 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3871 }
3872 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1"))
3873 {
3874 if(m_vendor_config.pData)
3875 {
3876 free(m_vendor_config.pData);
3877 m_vendor_config.pData = NULL;
3878 m_vendor_config.nDataSize = 0;
3879 }
3880
3881 if (((*((OMX_U32 *) config->pData)) &
3882 VC1_SP_MP_START_CODE_MASK) ==
3883 VC1_SP_MP_START_CODE)
3884 {
3885 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3886 m_vendor_config.nPortIndex = config->nPortIndex;
3887 m_vendor_config.nDataSize = config->nDataSize;
3888 m_vendor_config.pData =
3889 (OMX_U8 *) malloc(config->nDataSize);
3890 memcpy(m_vendor_config.pData, config->pData,
3891 config->nDataSize);
3892 m_vc1_profile = VC1_SP_MP_RCV;
3893 }
3894 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
3895 {
3896 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3897 m_vendor_config.nPortIndex = config->nPortIndex;
3898 m_vendor_config.nDataSize = config->nDataSize;
3899 m_vendor_config.pData =
3900 (OMX_U8 *) malloc((config->nDataSize));
3901 memcpy(m_vendor_config.pData, config->pData,
3902 config->nDataSize);
3903 m_vc1_profile = VC1_AP;
3904 }
3905 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
3906 {
3907 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3908 m_vendor_config.nPortIndex = config->nPortIndex;
3909 m_vendor_config.nDataSize = config->nDataSize;
3910 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3911 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3912 m_vc1_profile = VC1_SP_MP_RCV;
3913 }
3914 else
3915 {
3916 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3917 }
3918 }
3919 return ret;
3920 }
3921 else if (configIndex == OMX_IndexConfigVideoNalSize)
3922 {
3923
3924 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3925 nal_length = pNal->nNaluBytes;
3926 m_frame_parser.init_nal_length(nal_length);
3927 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length);
3928 return ret;
3929 }
3930
3931 return OMX_ErrorNotImplemented;
3932}
3933
3934/* ======================================================================
3935FUNCTION
3936 omx_vdec::GetExtensionIndex
3937
3938DESCRIPTION
3939 OMX GetExtensionIndex method implementaion. <TBD>
3940
3941PARAMETERS
3942 <TBD>.
3943
3944RETURN VALUE
3945 OMX Error None if everything successful.
3946
3947========================================================================== */
3948OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3949 OMX_IN OMX_STRING paramName,
3950 OMX_OUT OMX_INDEXTYPE* indexType)
3951{
3952 if(m_state == OMX_StateInvalid)
3953 {
3954 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3955 return OMX_ErrorInvalidState;
3956 }
3957 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3958 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3959 }
3960 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
3961 {
3962 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3963 }
3964#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3965 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
3966 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
3967 }
3968 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
3969 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
3970 }
3971 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
3972 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3973 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
3974 }
3975 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
3976 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3977 }
3978#endif
3979 else {
3980 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3981 return OMX_ErrorNotImplemented;
3982 }
3983 return OMX_ErrorNone;
3984}
3985
3986/* ======================================================================
3987FUNCTION
3988 omx_vdec::GetState
3989
3990DESCRIPTION
3991 Returns the state information back to the caller.<TBD>
3992
3993PARAMETERS
3994 <TBD>.
3995
3996RETURN VALUE
3997 Error None if everything is successful.
3998========================================================================== */
3999OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
4000 OMX_OUT OMX_STATETYPE* state)
4001{
4002 *state = m_state;
4003 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
4004 return OMX_ErrorNone;
4005}
4006
4007/* ======================================================================
4008FUNCTION
4009 omx_vdec::ComponentTunnelRequest
4010
4011DESCRIPTION
4012 OMX Component Tunnel Request method implementation. <TBD>
4013
4014PARAMETERS
4015 None.
4016
4017RETURN VALUE
4018 OMX Error None if everything successful.
4019
4020========================================================================== */
4021OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
4022 OMX_IN OMX_U32 port,
4023 OMX_IN OMX_HANDLETYPE peerComponent,
4024 OMX_IN OMX_U32 peerPort,
4025 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
4026{
4027 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
4028 return OMX_ErrorNotImplemented;
4029}
4030
4031/* ======================================================================
4032FUNCTION
4033 omx_vdec::UseOutputBuffer
4034
4035DESCRIPTION
4036 Helper function for Use buffer in the input pin
4037
4038PARAMETERS
4039 None.
4040
4041RETURN VALUE
4042 true/false
4043
4044========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004045OMX_ERRORTYPE omx_vdec::allocate_extradata()
4046{
4047#ifdef USE_ION
4048 if (drv_ctx.extradata_info.buffer_size) {
4049 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4050 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4051 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4052 free_ion_memory(&drv_ctx.extradata_info.ion);
4053 }
4054 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4055 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4056 drv_ctx.extradata_info.count * drv_ctx.extradata_info.size, 4096,
4057 &drv_ctx.extradata_info.ion.ion_alloc_data,
4058 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4059 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
4060 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
4061 return OMX_ErrorInsufficientResources;
4062 }
4063 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4064 drv_ctx.extradata_info.size,
4065 PROT_READ|PROT_WRITE, MAP_SHARED,
4066 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4067 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
4068 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
4069 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4070 free_ion_memory(&drv_ctx.extradata_info.ion);
4071 return OMX_ErrorInsufficientResources;
4072 }
4073 }
4074#endif
4075 return OMX_ErrorNone;
4076}
4077
4078void omx_vdec::free_extradata() {
4079#ifdef USE_ION
4080 if (drv_ctx.extradata_info.uaddr) {
4081 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4082 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4083 free_ion_memory(&drv_ctx.extradata_info.ion);
4084 }
4085 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
4086#endif
4087}
4088
Shalaj Jain273b3e02012-06-22 19:08:03 -07004089OMX_ERRORTYPE omx_vdec::use_output_buffer(
4090 OMX_IN OMX_HANDLETYPE hComp,
4091 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4092 OMX_IN OMX_U32 port,
4093 OMX_IN OMX_PTR appData,
4094 OMX_IN OMX_U32 bytes,
4095 OMX_IN OMX_U8* buffer)
4096{
4097 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4098 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4099 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004100 struct vdec_setbuffer_cmd setbuffers;
4101 OMX_PTR privateAppData = NULL;
4102 private_handle_t *handle = NULL;
4103 OMX_U8 *buff = buffer;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004104 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004105 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4106 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004107
Shalaj Jain273b3e02012-06-22 19:08:03 -07004108 if (!m_out_mem_ptr) {
4109 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4110 eRet = allocate_output_headers();
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004111 if (eRet == OMX_ErrorNone)
4112 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004113 }
4114
4115 if (eRet == OMX_ErrorNone) {
4116 for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
4117 if(BITMASK_ABSENT(&m_out_bm_count,i))
4118 {
4119 break;
4120 }
4121 }
4122 }
4123
4124 if(i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004125 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004126 eRet = OMX_ErrorInsufficientResources;
4127 }
4128
4129 if (eRet == OMX_ErrorNone) {
4130#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
4131 if(m_enable_android_native_buffers) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004132 if (m_use_android_native_buffers) {
4133 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4134 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4135 handle = (private_handle_t *)nBuf->handle;
4136 privateAppData = params->pAppPrivate;
4137 } else {
4138 handle = (private_handle_t *)buff;
4139 privateAppData = appData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004140 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004141
4142 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4143 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4144 " expected %u, got %lu",
4145 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4146 return OMX_ErrorBadParameter;
4147 }
4148
4149 if (!m_use_android_native_buffers) {
4150 if (!secure_mode) {
4151 buff = (OMX_U8*)mmap(0, handle->size,
4152 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4153 if (buff == MAP_FAILED) {
4154 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4155 return OMX_ErrorInsufficientResources;
4156 }
4157 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004158 }
4159#if defined(_ANDROID_ICS_)
4160 native_buffer[i].nativehandle = handle;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004161 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004162#endif
4163 if(!handle) {
4164 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4165 return OMX_ErrorBadParameter;
4166 }
4167 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4168 drv_ctx.ptr_outputbuffer[i].offset = 0;
4169 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4170 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4171 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4172 } else
4173#endif
4174
4175 if (!ouput_egl_buffers && !m_use_output_pmem) {
4176#ifdef USE_ION
4177 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4178 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4179 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004180 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004181 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004182 DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004183 return OMX_ErrorInsufficientResources;
4184 }
4185 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4186 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4187#else
4188 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4189 open (MEM_DEVICE,O_RDWR);
4190
4191 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004192 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004193 return OMX_ErrorInsufficientResources;
4194 }
4195
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004196 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004197 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0)
4198 {
4199 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4200 open (MEM_DEVICE,O_RDWR);
4201 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004202 DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004203 return OMX_ErrorInsufficientResources;
4204 }
4205 }
4206
4207 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4208 drv_ctx.op_buf.buffer_size,
4209 drv_ctx.op_buf.alignment))
4210 {
4211 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4212 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4213 return OMX_ErrorInsufficientResources;
4214 }
4215#endif
4216 if(!secure_mode) {
4217 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4218 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4219 PROT_READ|PROT_WRITE, MAP_SHARED,
4220 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4221 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4222 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4223#ifdef USE_ION
4224 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4225#endif
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004226 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004227 return OMX_ErrorInsufficientResources;
4228 }
4229 }
4230 drv_ctx.ptr_outputbuffer[i].offset = 0;
4231 privateAppData = appData;
4232 }
4233 else {
4234
4235 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4236 if (!appData || !bytes ) {
4237 if(!secure_mode && !buffer) {
4238 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4239 return OMX_ErrorBadParameter;
4240 }
4241 }
4242
4243 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4244 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4245 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4246 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4247 !pmem_list->nEntries ||
4248 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4249 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4250 return OMX_ErrorBadParameter;
4251 }
4252 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4253 pmem_list->entryList->entry;
4254 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x",
4255 pmem_info->pmem_fd);
4256 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4257 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4258 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4259 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4260 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4261 privateAppData = appData;
4262 }
4263 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4264 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4265
4266 *bufferHdr = (m_out_mem_ptr + i );
4267 if(secure_mode)
4268 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4269 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4270 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4271 sizeof (vdec_bufferpayload));
4272
Shalaj Jain286b0062013-02-21 20:35:48 -08004273 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
4274 drv_ctx.ptr_outputbuffer[i].bufferaddr,
4275 drv_ctx.ptr_outputbuffer[i].pmem_fd );
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004276
4277 buf.index = i;
4278 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4279 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004280 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08004281 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
4282 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004283 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4284 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4285 plane[0].data_offset = 0;
4286 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4287 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4288 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4289 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4290#ifdef USE_ION
4291 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4292#endif
4293 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4294 plane[extra_idx].data_offset = 0;
4295 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4296 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
4297 return OMX_ErrorBadParameter;
4298 }
4299 buf.m.planes = plane;
4300 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004301
4302 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]);
4303
4304 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4305 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4306 /*TODO: How to handle this case */
4307 return OMX_ErrorInsufficientResources;
4308 }
4309
4310 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4311 enum v4l2_buf_type buf_type;
4312 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4313 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4314 return OMX_ErrorInsufficientResources;
4315 } else {
4316 streaming[CAPTURE_PORT] = true;
4317 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4318 }
4319 }
4320
Shalaj Jain273b3e02012-06-22 19:08:03 -07004321 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004322 if (m_enable_android_native_buffers) {
4323 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4324 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4325 } else {
4326 (*bufferHdr)->pBuffer = buff;
4327 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004328 (*bufferHdr)->pAppPrivate = privateAppData;
4329 BITMASK_SET(&m_out_bm_count,i);
4330 }
4331 return eRet;
4332}
4333
4334/* ======================================================================
4335FUNCTION
4336 omx_vdec::use_input_heap_buffers
4337
4338DESCRIPTION
4339 OMX Use Buffer Heap allocation method implementation.
4340
4341PARAMETERS
4342 <TBD>.
4343
4344RETURN VALUE
4345 OMX Error None , if everything successful.
4346
4347========================================================================== */
4348OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
4349 OMX_IN OMX_HANDLETYPE hComp,
4350 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4351 OMX_IN OMX_U32 port,
4352 OMX_IN OMX_PTR appData,
4353 OMX_IN OMX_U32 bytes,
4354 OMX_IN OMX_U8* buffer)
4355{
4356 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4357 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4358 if(!m_inp_heap_ptr)
4359 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4360 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4361 drv_ctx.ip_buf.actualcount);
4362 if(!m_phdr_pmem_ptr)
4363 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4364 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4365 drv_ctx.ip_buf.actualcount);
4366 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
4367 {
4368 DEBUG_PRINT_ERROR("Insufficent memory");
4369 eRet = OMX_ErrorInsufficientResources;
4370 }
4371 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
4372 {
4373 input_use_buffer = true;
4374 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4375 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4376 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4377 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4378 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4379 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4380 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4381 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4382 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
Shalaj Jain286b0062013-02-21 20:35:48 -08004383 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
4384 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004385 {
4386 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4387 return OMX_ErrorInsufficientResources;
4388 }
4389 m_in_alloc_cnt++;
4390 }
4391 else
4392 {
4393 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4394 eRet = OMX_ErrorInsufficientResources;
4395 }
4396 return eRet;
4397}
4398
4399/* ======================================================================
4400FUNCTION
4401 omx_vdec::UseBuffer
4402
4403DESCRIPTION
4404 OMX Use Buffer method implementation.
4405
4406PARAMETERS
4407 <TBD>.
4408
4409RETURN VALUE
4410 OMX Error None , if everything successful.
4411
4412========================================================================== */
4413OMX_ERRORTYPE omx_vdec::use_buffer(
4414 OMX_IN OMX_HANDLETYPE hComp,
4415 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4416 OMX_IN OMX_U32 port,
4417 OMX_IN OMX_PTR appData,
4418 OMX_IN OMX_U32 bytes,
4419 OMX_IN OMX_U8* buffer)
4420{
4421 OMX_ERRORTYPE error = OMX_ErrorNone;
4422 struct vdec_setbuffer_cmd setbuffers;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004423
4424 if (bufferHdr == NULL || bytes == 0)
4425 {
4426 if(!secure_mode && buffer == NULL) {
4427 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4428 return OMX_ErrorBadParameter;
4429 }
4430 }
4431 if(m_state == OMX_StateInvalid)
4432 {
4433 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4434 return OMX_ErrorInvalidState;
4435 }
4436 if(port == OMX_CORE_INPUT_PORT_INDEX)
4437 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4438 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4439 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4440 else
4441 {
4442 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4443 error = OMX_ErrorBadPortIndex;
4444 }
4445 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error);
4446 if(error == OMX_ErrorNone)
4447 {
4448 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4449 {
4450 // Send the callback now
4451 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4452 post_event(OMX_CommandStateSet,OMX_StateIdle,
4453 OMX_COMPONENT_GENERATE_EVENT);
4454 }
4455 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4456 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4457 {
4458 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4459 post_event(OMX_CommandPortEnable,
4460 OMX_CORE_INPUT_PORT_INDEX,
4461 OMX_COMPONENT_GENERATE_EVENT);
4462 }
4463 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4464 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4465 {
4466 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4467 post_event(OMX_CommandPortEnable,
4468 OMX_CORE_OUTPUT_PORT_INDEX,
4469 OMX_COMPONENT_GENERATE_EVENT);
4470 }
4471 }
4472 return error;
4473}
4474
4475OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4476 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4477{
4478 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes)
4479 {
4480 if(m_inp_heap_ptr[bufferindex].pBuffer)
4481 free(m_inp_heap_ptr[bufferindex].pBuffer);
4482 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4483 }
4484 if (pmem_bufferHdr)
4485 free_input_buffer(pmem_bufferHdr);
4486 return OMX_ErrorNone;
4487}
4488
4489OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4490{
4491 unsigned int index = 0;
4492 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
4493 {
4494 return OMX_ErrorBadParameter;
4495 }
4496
4497 index = bufferHdr - m_inp_mem_ptr;
4498 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4499
4500 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer)
4501 {
4502 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4503 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0)
4504 {
Shalaj Jain273b3e02012-06-22 19:08:03 -07004505 struct vdec_setbuffer_cmd setbuffers;
4506 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4507 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4508 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004509 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4510 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4511 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %d",
4512 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4513 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4514 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4515 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4516 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4517 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4518 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr)
4519 {
4520 free(m_desc_buffer_ptr[index].buf_addr);
4521 m_desc_buffer_ptr[index].buf_addr = NULL;
4522 m_desc_buffer_ptr[index].desc_data_size = 0;
4523 }
4524#ifdef USE_ION
4525 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4526#endif
4527 }
4528 }
4529
4530 return OMX_ErrorNone;
4531}
4532
4533OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4534{
4535 unsigned int index = 0;
4536
4537 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
4538 {
4539 return OMX_ErrorBadParameter;
4540 }
4541
4542 index = bufferHdr - m_out_mem_ptr;
4543 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
4544
4545 if (index < drv_ctx.op_buf.actualcount
4546 && drv_ctx.ptr_outputbuffer)
4547 {
4548 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index,
4549 drv_ctx.ptr_outputbuffer[index].bufferaddr);
4550
Shalaj Jain273b3e02012-06-22 19:08:03 -07004551 struct vdec_setbuffer_cmd setbuffers;
4552 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4553 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4554 sizeof (vdec_bufferpayload));
Shalaj Jain273b3e02012-06-22 19:08:03 -07004555#ifdef _ANDROID_
4556 if(m_enable_android_native_buffers) {
4557 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4558 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4559 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4560 }
4561 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4562 } else {
4563#endif
4564 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
4565 {
4566 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4567 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4568 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %d",
Shalaj Jain4a9f77d2012-11-01 16:47:33 -07004569 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004570 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4571 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
Shalaj Jain4a9f77d2012-11-01 16:47:33 -07004572 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004573 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4574 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
4575#ifdef USE_ION
4576 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
4577#endif
4578 }
4579#ifdef _ANDROID_
4580 }
4581#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004582 if (release_output_done()) {
4583 free_extradata();
4584 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004585 }
4586
4587 return OMX_ErrorNone;
4588
4589}
4590
4591OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
4592 OMX_BUFFERHEADERTYPE **bufferHdr,
4593 OMX_U32 port,
4594 OMX_PTR appData,
4595 OMX_U32 bytes)
4596{
4597 OMX_BUFFERHEADERTYPE *input = NULL;
4598 unsigned char *buf_addr = NULL;
4599 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4600 unsigned i = 0;
4601
4602 /* Sanity Check*/
4603 if (bufferHdr == NULL)
4604 {
4605 return OMX_ErrorBadParameter;
4606 }
4607
4608 if (m_inp_heap_ptr == NULL)
4609 {
4610 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4611 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4612 drv_ctx.ip_buf.actualcount);
4613 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4614 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4615 drv_ctx.ip_buf.actualcount);
4616
4617 if (m_inp_heap_ptr == NULL)
4618 {
4619 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4620 return OMX_ErrorInsufficientResources;
4621 }
4622 }
4623
4624 /*Find a Free index*/
4625 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4626 {
4627 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
4628 {
4629 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4630 break;
4631 }
4632 }
4633
4634 if (i < drv_ctx.ip_buf.actualcount)
4635 {
4636 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4637
4638 if (buf_addr == NULL)
4639 {
4640 return OMX_ErrorInsufficientResources;
4641 }
4642
4643 *bufferHdr = (m_inp_heap_ptr + i);
4644 input = *bufferHdr;
4645 BITMASK_SET(&m_heap_inp_bm_count,i);
4646
4647 input->pBuffer = (OMX_U8 *)buf_addr;
4648 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4649 input->nVersion.nVersion = OMX_SPEC_VERSION;
4650 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4651 input->pAppPrivate = appData;
4652 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4653 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4654 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
Shalaj Jain286b0062013-02-21 20:35:48 -08004655 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004656 /*Add the Buffers to freeq*/
Shalaj Jain286b0062013-02-21 20:35:48 -08004657 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
4658 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07004659 {
4660 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4661 return OMX_ErrorInsufficientResources;
4662 }
4663 }
4664 else
4665 {
4666 return OMX_ErrorBadParameter;
4667 }
4668
4669 return eRet;
4670
4671}
4672
4673
4674/* ======================================================================
4675FUNCTION
4676 omx_vdec::AllocateInputBuffer
4677
4678DESCRIPTION
4679 Helper function for allocate buffer in the input pin
4680
4681PARAMETERS
4682 None.
4683
4684RETURN VALUE
4685 true/false
4686
4687========================================================================== */
4688OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
4689 OMX_IN OMX_HANDLETYPE hComp,
4690 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4691 OMX_IN OMX_U32 port,
4692 OMX_IN OMX_PTR appData,
4693 OMX_IN OMX_U32 bytes)
4694{
4695
4696 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4697 struct vdec_setbuffer_cmd setbuffers;
4698 OMX_BUFFERHEADERTYPE *input = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004699 unsigned i = 0;
4700 unsigned char *buf_addr = NULL;
4701 int pmem_fd = -1;
4702
4703 if(bytes != drv_ctx.ip_buf.buffer_size)
4704 {
4705 DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d",
4706 bytes, drv_ctx.ip_buf.buffer_size);
4707 return OMX_ErrorBadParameter;
4708 }
4709
4710 if(!m_inp_mem_ptr)
4711 {
4712 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4713 drv_ctx.ip_buf.actualcount,
4714 drv_ctx.ip_buf.buffer_size);
4715
4716 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4717 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4718
4719 if (m_inp_mem_ptr == NULL)
4720 {
4721 return OMX_ErrorInsufficientResources;
4722 }
4723
4724 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4725 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4726
4727 if (drv_ctx.ptr_inputbuffer == NULL)
4728 {
4729 return OMX_ErrorInsufficientResources;
4730 }
4731#ifdef USE_ION
4732 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4733 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4734
4735 if (drv_ctx.ip_buf_ion_info == NULL)
4736 {
4737 return OMX_ErrorInsufficientResources;
4738 }
4739#endif
4740
4741 for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
4742 {
4743 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4744#ifdef USE_ION
4745 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4746#endif
4747 }
4748 }
4749
4750 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4751 {
4752 if(BITMASK_ABSENT(&m_inp_bm_count,i))
4753 {
4754 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4755 break;
4756 }
4757 }
4758
4759 if(i < drv_ctx.ip_buf.actualcount)
4760 {
4761 struct v4l2_buffer buf;
4762 struct v4l2_plane plane;
4763 int rc;
4764 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4765#ifdef USE_ION
4766 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4767 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4768 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004769 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004770 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4771 return OMX_ErrorInsufficientResources;
4772 }
4773 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4774#else
4775 pmem_fd = open (MEM_DEVICE,O_RDWR);
4776
4777 if (pmem_fd < 0)
4778 {
4779 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4780 return OMX_ErrorInsufficientResources;
4781 }
4782
4783 if (pmem_fd == 0)
4784 {
4785 pmem_fd = open (MEM_DEVICE,O_RDWR);
4786
4787 if (pmem_fd < 0)
4788 {
4789 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4790 return OMX_ErrorInsufficientResources;
4791 }
4792 }
4793
4794 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4795 drv_ctx.ip_buf.alignment))
4796 {
4797 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4798 close(pmem_fd);
4799 return OMX_ErrorInsufficientResources;
4800 }
4801#endif
4802 if (!secure_mode) {
4803 buf_addr = (unsigned char *)mmap(NULL,
4804 drv_ctx.ip_buf.buffer_size,
4805 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4806
4807 if (buf_addr == MAP_FAILED)
4808 {
4809 close(pmem_fd);
4810#ifdef USE_ION
4811 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4812#endif
4813 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4814 return OMX_ErrorInsufficientResources;
4815 }
4816 }
4817 *bufferHdr = (m_inp_mem_ptr + i);
4818 if (secure_mode)
4819 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4820 else
4821 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4822 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4823 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4824 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4825 drv_ctx.ptr_inputbuffer [i].offset = 0;
4826
4827
4828 buf.index = i;
4829 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4830 buf.memory = V4L2_MEMORY_USERPTR;
4831 plane.bytesused = 0;
4832 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4833 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4834 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4835 plane.reserved[1] = 0;
4836 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4837 buf.m.planes = &plane;
4838 buf.length = 1;
4839
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004840 DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_inputbuffer[i]);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004841
4842 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4843
4844 if (rc) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07004845 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004846 /*TODO: How to handle this case */
4847 return OMX_ErrorInsufficientResources;
4848 }
4849
4850 input = *bufferHdr;
4851 BITMASK_SET(&m_inp_bm_count,i);
4852 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4853 if (secure_mode)
4854 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4855 else
4856 input->pBuffer = (OMX_U8 *)buf_addr;
4857 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4858 input->nVersion.nVersion = OMX_SPEC_VERSION;
4859 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4860 input->pAppPrivate = appData;
4861 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4862 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4863
4864 if (drv_ctx.disable_dmx)
4865 {
4866 eRet = allocate_desc_buffer(i);
4867 }
4868 }
4869 else
4870 {
4871 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4872 eRet = OMX_ErrorInsufficientResources;
4873 }
4874 return eRet;
4875}
4876
4877
4878/* ======================================================================
4879FUNCTION
4880 omx_vdec::AllocateOutputBuffer
4881
4882DESCRIPTION
4883 Helper fn for AllocateBuffer in the output pin
4884
4885PARAMETERS
4886 <TBD>.
4887
4888RETURN VALUE
4889 OMX Error None if everything went well.
4890
4891========================================================================== */
4892OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
4893 OMX_IN OMX_HANDLETYPE hComp,
4894 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4895 OMX_IN OMX_U32 port,
4896 OMX_IN OMX_PTR appData,
4897 OMX_IN OMX_U32 bytes)
4898{
4899 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4900 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4901 unsigned i= 0; // Temporary counter
Shalaj Jain273b3e02012-06-22 19:08:03 -07004902 struct vdec_setbuffer_cmd setbuffers;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004903 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004904#ifdef USE_ION
4905 int ion_device_fd =-1;
4906 struct ion_allocation_data ion_alloc_data;
4907 struct ion_fd_data fd_ion_data;
4908#endif
4909 if(!m_out_mem_ptr)
4910 {
4911 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4912 drv_ctx.op_buf.actualcount,
4913 drv_ctx.op_buf.buffer_size);
4914 int nBufHdrSize = 0;
4915 int nPlatformEntrySize = 0;
4916 int nPlatformListSize = 0;
4917 int nPMEMInfoSize = 0;
4918 int pmem_fd = -1;
4919 unsigned char *pmem_baseaddress = NULL;
4920
4921 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4922 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4923 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
4924
4925 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4926 drv_ctx.op_buf.actualcount);
4927 nBufHdrSize = drv_ctx.op_buf.actualcount *
4928 sizeof(OMX_BUFFERHEADERTYPE);
4929
4930 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4931 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4932 nPlatformListSize = drv_ctx.op_buf.actualcount *
4933 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4934 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4935 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
4936
4937 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4938 sizeof(OMX_BUFFERHEADERTYPE),
4939 nPMEMInfoSize,
4940 nPlatformListSize);
4941 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4942 drv_ctx.op_buf.actualcount);
4943#ifdef USE_ION
4944 ion_device_fd = alloc_map_ion_memory(
4945 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4946 drv_ctx.op_buf.alignment,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004947 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004948 if (ion_device_fd < 0) {
4949 return OMX_ErrorInsufficientResources;
4950 }
4951 pmem_fd = fd_ion_data.fd;
4952#else
4953 pmem_fd = open (MEM_DEVICE,O_RDWR);
4954
4955 if (pmem_fd < 0)
4956 {
4957 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4958 drv_ctx.op_buf.buffer_size);
4959 return OMX_ErrorInsufficientResources;
4960 }
4961
4962 if(pmem_fd == 0)
4963 {
4964 pmem_fd = open (MEM_DEVICE,O_RDWR);
4965
4966 if (pmem_fd < 0)
4967 {
4968 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4969 drv_ctx.op_buf.buffer_size);
4970 return OMX_ErrorInsufficientResources;
4971 }
4972 }
4973
4974 if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4975 drv_ctx.op_buf.actualcount,
4976 drv_ctx.op_buf.alignment))
4977 {
4978 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4979 close(pmem_fd);
4980 return OMX_ErrorInsufficientResources;
4981 }
4982#endif
4983 if (!secure_mode) {
4984 pmem_baseaddress = (unsigned char *)mmap(NULL,
4985 (drv_ctx.op_buf.buffer_size *
4986 drv_ctx.op_buf.actualcount),
4987 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4988 if (pmem_baseaddress == MAP_FAILED)
4989 {
4990 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4991 drv_ctx.op_buf.buffer_size);
4992 close(pmem_fd);
4993#ifdef USE_ION
4994 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4995#endif
4996 return OMX_ErrorInsufficientResources;
4997 }
4998 }
4999 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5000 // Alloc mem for platform specific info
5001 char *pPtr=NULL;
5002 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5003 nPMEMInfoSize,1);
5004 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5005 calloc (sizeof(struct vdec_bufferpayload),
5006 drv_ctx.op_buf.actualcount);
5007 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5008 calloc (sizeof (struct vdec_output_frameinfo),
5009 drv_ctx.op_buf.actualcount);
5010#ifdef USE_ION
5011 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5012 calloc (sizeof(struct vdec_ion),
5013 drv_ctx.op_buf.actualcount);
5014#endif
5015
5016 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5017 && drv_ctx.ptr_respbuffer)
5018 {
5019 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5020 (drv_ctx.op_buf.buffer_size *
5021 drv_ctx.op_buf.actualcount);
5022 bufHdr = m_out_mem_ptr;
5023 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5024 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5025 (((char *) m_platform_list) + nPlatformListSize);
5026 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5027 (((char *) m_platform_entry) + nPlatformEntrySize);
5028 pPlatformList = m_platform_list;
5029 pPlatformEntry = m_platform_entry;
5030 pPMEMInfo = m_pmem_info;
5031
5032 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
5033
5034 // Settting the entire storage nicely
5035 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
5036 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
5037 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
5038 {
5039 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5040 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5041 // Set the values when we determine the right HxW param
5042 bufHdr->nAllocLen = bytes;
5043 bufHdr->nFilledLen = 0;
5044 bufHdr->pAppPrivate = appData;
5045 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5046 // Platform specific PMEM Information
5047 // Initialize the Platform Entry
5048 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
5049 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5050 pPlatformEntry->entry = pPMEMInfo;
5051 // Initialize the Platform List
5052 pPlatformList->nEntries = 1;
5053 pPlatformList->entryList = pPlatformEntry;
5054 // Keep pBuffer NULL till vdec is opened
5055 bufHdr->pBuffer = NULL;
5056 bufHdr->nOffset = 0;
5057
5058 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5059 pPMEMInfo->pmem_fd = 0;
5060 bufHdr->pPlatformPrivate = pPlatformList;
5061
5062 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
Vinay Kalia53fa6832012-10-11 17:55:30 -07005063 m_pmem_info[i].pmem_fd = pmem_fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005064#ifdef USE_ION
5065 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5066 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5067 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5068#endif
5069
5070 /*Create a mapping between buffers*/
5071 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5072 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5073 &drv_ctx.ptr_outputbuffer[i];
5074 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5075 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5076 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
5077
5078 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
5079 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5080 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5081 // Move the buffer and buffer header pointers
5082 bufHdr++;
5083 pPMEMInfo++;
5084 pPlatformEntry++;
5085 pPlatformList++;
5086 }
5087 }
5088 else
5089 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005090 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07005091 m_out_mem_ptr, pPtr);
5092 if(m_out_mem_ptr)
5093 {
5094 free(m_out_mem_ptr);
5095 m_out_mem_ptr = NULL;
5096 }
5097 if(pPtr)
5098 {
5099 free(pPtr);
5100 pPtr = NULL;
5101 }
5102 if(drv_ctx.ptr_outputbuffer)
5103 {
5104 free(drv_ctx.ptr_outputbuffer);
5105 drv_ctx.ptr_outputbuffer = NULL;
5106 }
5107 if(drv_ctx.ptr_respbuffer)
5108 {
5109 free(drv_ctx.ptr_respbuffer);
5110 drv_ctx.ptr_respbuffer = NULL;
5111 }
5112#ifdef USE_ION
5113 if (drv_ctx.op_buf_ion_info) {
5114 DEBUG_PRINT_LOW("\n Free o/p ion context");
5115 free(drv_ctx.op_buf_ion_info);
5116 drv_ctx.op_buf_ion_info = NULL;
5117 }
5118#endif
5119 eRet = OMX_ErrorInsufficientResources;
5120 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005121 if (eRet == OMX_ErrorNone)
5122 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005123 }
5124
5125 for(i=0; i< drv_ctx.op_buf.actualcount; i++)
5126 {
5127 if(BITMASK_ABSENT(&m_out_bm_count,i))
5128 {
5129 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
5130 break;
5131 }
5132 }
5133
5134 if (eRet == OMX_ErrorNone)
5135 {
5136 if(i < drv_ctx.op_buf.actualcount)
5137 {
5138 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005139 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Shalaj Jain273b3e02012-06-22 19:08:03 -07005140 int rc;
5141 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5142
5143 drv_ctx.ptr_outputbuffer[i].buffer_len =
5144 drv_ctx.op_buf.buffer_size;
5145
5146 *bufferHdr = (m_out_mem_ptr + i );
5147 if (secure_mode) {
5148 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5149 }
5150 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5151
5152 buf.index = i;
5153 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5154 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005155 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005156 plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
5157 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005158#ifdef USE_ION
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005159 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005160#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005161 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5162 plane[0].data_offset = 0;
5163 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5164 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5165 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5166 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
5167#ifdef USE_ION
5168 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5169#endif
5170 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5171 plane[extra_idx].data_offset = 0;
5172 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5173 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5174 return OMX_ErrorBadParameter;
5175 }
5176 buf.m.planes = plane;
5177 buf.length = drv_ctx.num_planes;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005178 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005179 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5180 if (rc) {
5181 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005182 return OMX_ErrorInsufficientResources;
5183 }
5184
5185 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5186 enum v4l2_buf_type buf_type;
5187 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5188 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5189 if (rc) {
5190 return OMX_ErrorInsufficientResources;
5191 } else {
5192 streaming[CAPTURE_PORT] = true;
5193 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5194 }
5195 }
5196
5197 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5198 (*bufferHdr)->pAppPrivate = appData;
5199 BITMASK_SET(&m_out_bm_count,i);
5200 }
5201 else
5202 {
5203 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5204 eRet = OMX_ErrorInsufficientResources;
5205 }
5206 }
5207
5208 return eRet;
5209}
5210
5211
5212// AllocateBuffer -- API Call
5213/* ======================================================================
5214FUNCTION
5215 omx_vdec::AllocateBuffer
5216
5217DESCRIPTION
5218 Returns zero if all the buffers released..
5219
5220PARAMETERS
5221 None.
5222
5223RETURN VALUE
5224 true/false
5225
5226========================================================================== */
5227OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
5228 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5229 OMX_IN OMX_U32 port,
5230 OMX_IN OMX_PTR appData,
5231 OMX_IN OMX_U32 bytes)
5232{
5233 unsigned i = 0;
5234 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5235
5236 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
5237 if(m_state == OMX_StateInvalid)
5238 {
5239 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5240 return OMX_ErrorInvalidState;
5241 }
5242
5243 if(port == OMX_CORE_INPUT_PORT_INDEX)
5244 {
5245 if (arbitrary_bytes)
5246 {
5247 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5248 }
5249 else
5250 {
5251 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5252 }
5253 }
5254 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5255 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005256 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5257 appData,bytes);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005258 }
5259 else
5260 {
5261 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5262 eRet = OMX_ErrorBadPortIndex;
5263 }
5264 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5265 if(eRet == OMX_ErrorNone)
5266 {
5267 if(allocate_done()){
5268 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
5269 {
5270 // Send the callback now
5271 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5272 post_event(OMX_CommandStateSet,OMX_StateIdle,
5273 OMX_COMPONENT_GENERATE_EVENT);
5274 }
5275 }
5276 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
5277 {
5278 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
5279 {
5280 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5281 post_event(OMX_CommandPortEnable,
5282 OMX_CORE_INPUT_PORT_INDEX,
5283 OMX_COMPONENT_GENERATE_EVENT);
5284 }
5285 }
5286 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
5287 {
5288 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
5289 {
5290 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5291 post_event(OMX_CommandPortEnable,
5292 OMX_CORE_OUTPUT_PORT_INDEX,
5293 OMX_COMPONENT_GENERATE_EVENT);
5294 }
5295 }
5296 }
5297 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5298 return eRet;
5299}
5300
5301// Free Buffer - API call
5302/* ======================================================================
5303FUNCTION
5304 omx_vdec::FreeBuffer
5305
5306DESCRIPTION
5307
5308PARAMETERS
5309 None.
5310
5311RETURN VALUE
5312 true/false
5313
5314========================================================================== */
5315OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
5316 OMX_IN OMX_U32 port,
5317 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5318{
5319 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5320 unsigned int nPortIndex;
5321 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5322
5323 if(m_state == OMX_StateIdle &&
5324 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5325 {
5326 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
5327 }
5328 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5329 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
5330 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005331 DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005332 }
5333 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
5334 {
5335 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5336 post_event(OMX_EventError,
5337 OMX_ErrorPortUnpopulated,
5338 OMX_COMPONENT_GENERATE_EVENT);
5339
5340 return OMX_ErrorIncorrectStateOperation;
5341 }
5342 else if (m_state != OMX_StateInvalid)
5343 {
5344 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5345 post_event(OMX_EventError,
5346 OMX_ErrorPortUnpopulated,
5347 OMX_COMPONENT_GENERATE_EVENT);
5348 }
5349
5350 if(port == OMX_CORE_INPUT_PORT_INDEX)
5351 {
5352 /*Check if arbitrary bytes*/
5353 if(!arbitrary_bytes && !input_use_buffer)
5354 nPortIndex = buffer - m_inp_mem_ptr;
5355 else
5356 nPortIndex = buffer - m_inp_heap_ptr;
5357
5358 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
5359 if(nPortIndex < drv_ctx.ip_buf.actualcount)
5360 {
5361 // Clear the bit associated with it.
5362 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5363 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5364 if (input_use_buffer == true)
5365 {
5366
5367 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5368 if(m_phdr_pmem_ptr)
5369 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5370 }
5371 else
5372 {
5373 if (arbitrary_bytes)
5374 {
5375 if(m_phdr_pmem_ptr)
5376 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5377 else
5378 free_input_buffer(nPortIndex,NULL);
5379 }
5380 else
5381 free_input_buffer(buffer);
5382 }
5383 m_inp_bPopulated = OMX_FALSE;
5384 /*Free the Buffer Header*/
5385 if (release_input_done())
5386 {
5387 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5388 free_input_buffer_header();
5389 }
5390 }
5391 else
5392 {
5393 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5394 eRet = OMX_ErrorBadPortIndex;
5395 }
5396
5397 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5398 && release_input_done())
5399 {
5400 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5401 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5402 post_event(OMX_CommandPortDisable,
5403 OMX_CORE_INPUT_PORT_INDEX,
5404 OMX_COMPONENT_GENERATE_EVENT);
5405 }
5406 }
5407 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5408 {
5409 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005410 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005411 if(nPortIndex < drv_ctx.op_buf.actualcount)
5412 {
5413 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5414 // Clear the bit associated with it.
5415 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5416 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005417 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005418
5419 if (release_output_done())
5420 {
5421 free_output_buffer_header();
5422 }
5423 }
5424 else
5425 {
5426 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5427 eRet = OMX_ErrorBadPortIndex;
5428 }
5429 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5430 && release_output_done())
5431 {
5432 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5433
5434 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5435 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5436#ifdef _ANDROID_ICS_
5437 if (m_enable_android_native_buffers)
5438 {
5439 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5440 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5441 }
5442#endif
5443
5444 post_event(OMX_CommandPortDisable,
5445 OMX_CORE_OUTPUT_PORT_INDEX,
5446 OMX_COMPONENT_GENERATE_EVENT);
5447 }
5448 }
5449 else
5450 {
5451 eRet = OMX_ErrorBadPortIndex;
5452 }
5453 if((eRet == OMX_ErrorNone) &&
5454 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5455 {
5456 if(release_done())
5457 {
5458 // Send the callback now
5459 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5460 post_event(OMX_CommandStateSet, OMX_StateLoaded,
5461 OMX_COMPONENT_GENERATE_EVENT);
5462 }
5463 }
5464 return eRet;
5465}
5466
5467
5468/* ======================================================================
5469FUNCTION
5470 omx_vdec::EmptyThisBuffer
5471
5472DESCRIPTION
5473 This routine is used to push the encoded video frames to
5474 the video decoder.
5475
5476PARAMETERS
5477 None.
5478
5479RETURN VALUE
5480 OMX Error None if everything went successful.
5481
5482========================================================================== */
5483OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5484 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5485{
5486 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5487 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5488
5489 if(m_state == OMX_StateInvalid)
5490 {
5491 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5492 return OMX_ErrorInvalidState;
5493 }
5494
5495 if (buffer == NULL)
5496 {
5497 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5498 return OMX_ErrorBadParameter;
5499 }
5500
5501 if (!m_inp_bEnabled)
5502 {
5503 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5504 return OMX_ErrorIncorrectStateOperation;
5505 }
5506
5507 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
5508 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005509 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005510 return OMX_ErrorBadPortIndex;
5511 }
5512
5513#ifdef _ANDROID_
5514 if(iDivXDrmDecrypt)
5515 {
5516 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5517 if(drmErr != OMX_ErrorNone) {
5518 // this error can be ignored
5519 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5520 }
5521 }
5522#endif //_ANDROID_
5523 if (perf_flag)
5524 {
5525 if (!latency)
5526 {
5527 dec_time.stop();
5528 latency = dec_time.processing_time_us();
5529 dec_time.start();
5530 }
5531 }
5532
5533 if (arbitrary_bytes)
5534 {
5535 nBufferIndex = buffer - m_inp_heap_ptr;
5536 }
5537 else
5538 {
5539 if (input_use_buffer == true)
5540 {
5541 nBufferIndex = buffer - m_inp_heap_ptr;
5542 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5543 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5544 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5545 buffer = &m_inp_mem_ptr[nBufferIndex];
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005546 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07005547 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5548 }
5549 else{
5550 nBufferIndex = buffer - m_inp_mem_ptr;
5551 }
5552 }
5553
5554 if (nBufferIndex > drv_ctx.ip_buf.actualcount )
5555 {
5556 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5557 return OMX_ErrorBadParameter;
5558 }
5559
5560 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5561 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5562 if (arbitrary_bytes)
5563 {
5564 post_event ((unsigned)hComp,(unsigned)buffer,
5565 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5566 }
5567 else
5568 {
5569 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5570 set_frame_rate(buffer->nTimeStamp);
5571 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5572 }
5573 return OMX_ErrorNone;
5574}
5575
5576/* ======================================================================
5577FUNCTION
5578 omx_vdec::empty_this_buffer_proxy
5579
5580DESCRIPTION
5581 This routine is used to push the encoded video frames to
5582 the video decoder.
5583
5584PARAMETERS
5585 None.
5586
5587RETURN VALUE
5588 OMX Error None if everything went successful.
5589
5590========================================================================== */
5591OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
5592 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5593{
5594 int push_cnt = 0,i=0;
5595 unsigned nPortIndex = 0;
5596 OMX_ERRORTYPE ret = OMX_ErrorNone;
5597 struct vdec_input_frameinfo frameinfo;
5598 struct vdec_bufferpayload *temp_buffer;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005599 struct vdec_seqheader seq_header;
5600 bool port_setting_changed = true;
5601 bool not_coded_vop = false;
5602
5603 /*Should we generate a Aync error event*/
5604 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
5605 {
5606 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5607 return OMX_ErrorBadParameter;
5608 }
5609
5610 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5611
5612 if (nPortIndex > drv_ctx.ip_buf.actualcount)
5613 {
5614 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5615 nPortIndex);
5616 return OMX_ErrorBadParameter;
5617 }
5618
5619 pending_input_buffers++;
5620
5621 /* return zero length and not an EOS buffer */
5622 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5623 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5624 {
5625 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5626 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5627 OMX_COMPONENT_GENERATE_EBD);
5628 return OMX_ErrorNone;
5629 }
5630
5631
5632 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){
5633 mp4StreamType psBits;
5634 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5635 psBits.numBytes = buffer->nFilledLen;
5636 mp4_headerparser.parseHeader(&psBits);
5637 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5638 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5639 if(not_coded_vop) {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005640 DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
Shalaj Jain273b3e02012-06-22 19:08:03 -07005641 buffer->nFilledLen,frame_count);
5642 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){
5643 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5644 not_coded_vop = false;
5645 buffer->nFilledLen = 0;
5646 }
5647 }
5648 }
5649
5650 if(input_flush_progress == true
5651
5652 || not_coded_vop
5653
5654 )
5655 {
5656 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5657 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5658 OMX_COMPONENT_GENERATE_EBD);
5659 return OMX_ErrorNone;
5660 }
5661
5662 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5663
5664 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
5665 {
5666 return OMX_ErrorBadParameter;
5667 }
5668
5669 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5670 /*for use buffer we need to memcpy the data*/
5671 temp_buffer->buffer_len = buffer->nFilledLen;
5672
5673 if (input_use_buffer)
5674 {
5675 if (buffer->nFilledLen <= temp_buffer->buffer_len)
5676 {
5677 if(arbitrary_bytes)
5678 {
5679 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5680 }
5681 else
5682 {
5683 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5684 buffer->nFilledLen);
5685 }
5686 }
5687 else
5688 {
5689 return OMX_ErrorBadParameter;
5690 }
5691
5692 }
5693
5694 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5695 frameinfo.client_data = (void *) buffer;
5696 frameinfo.datalen = temp_buffer->buffer_len;
5697 frameinfo.flags = 0;
5698 frameinfo.offset = buffer->nOffset;
5699 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5700 frameinfo.pmem_offset = temp_buffer->offset;
5701 frameinfo.timestamp = buffer->nTimeStamp;
5702 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr)
5703 {
5704 DEBUG_PRINT_LOW("ETB: dmx enabled");
5705 if (m_demux_entries == 0)
5706 {
5707 extract_demux_addr_offsets(buffer);
5708 }
5709
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07005710 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005711 handle_demux_data(buffer);
5712 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5713 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5714 }
5715 else
5716 {
5717 frameinfo.desc_addr = NULL;
5718 frameinfo.desc_size = 0;
5719 }
5720 if(!arbitrary_bytes)
5721 {
5722 frameinfo.flags |= buffer->nFlags;
5723 }
5724
5725#ifdef _ANDROID_
5726 if (m_debug_timestamp)
5727 {
5728 if(arbitrary_bytes)
5729 {
5730 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5731 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5732 }
5733 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG))
5734 {
5735 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5736 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5737 }
5738 }
5739#endif
5740
5741#ifdef INPUT_BUFFER_LOG
5742 if (inputBufferFile1)
5743 {
5744 fwrite((const char *)temp_buffer->bufferaddr,
5745 temp_buffer->buffer_len,1,inputBufferFile1);
5746 }
5747#endif
5748
5749 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
5750 {
5751 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5752 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5753 }
5754
5755 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5756 {
5757 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5758 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5759 h264_scratch.nFilledLen = 0;
5760 nal_count = 0;
5761 look_ahead_nal = false;
5762 frame_count = 0;
5763 if (m_frame_parser.mutils)
5764 m_frame_parser.mutils->initialize_frame_checking_environment();
5765 m_frame_parser.flush();
5766 h264_last_au_ts = LLONG_MAX;
5767 h264_last_au_flags = 0;
5768 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5769 m_demux_entries = 0;
5770 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08005771 struct v4l2_buffer buf;
5772 struct v4l2_plane plane;
5773 memset( (void *)&buf, 0, sizeof(buf));
5774 memset( (void *)&plane, 0, sizeof(plane));
5775 int rc;
5776 unsigned long print_count;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005777 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5778 { buf.flags = V4L2_BUF_FLAG_EOS;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005779 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005780 }
5781 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5782 buf.index = nPortIndex;
5783 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5784 buf.memory = V4L2_MEMORY_USERPTR;
5785 plane.bytesused = temp_buffer->buffer_len;
5786 plane.length = drv_ctx.ip_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005787 plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
5788 (unsigned long)temp_buffer->offset;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005789 plane.reserved[0] = temp_buffer->pmem_fd;
5790 plane.reserved[1] = temp_buffer->offset;
5791 plane.data_offset = 0;
5792 buf.m.planes = &plane;
5793 buf.length = 1;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08005794 if (frameinfo.timestamp >= LLONG_MAX) {
5795 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5796 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07005797 //assumption is that timestamp is in milliseconds
5798 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5799 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005800 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5801
Shalaj Jain273b3e02012-06-22 19:08:03 -07005802 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
Praneeth Paladugu268314a2012-08-23 11:33:28 -07005803 if(rc)
5804 {
5805 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5806 return OMX_ErrorHardware;
5807 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005808 if(!streaming[OUTPUT_PORT])
5809 {
5810 enum v4l2_buf_type buf_type;
5811 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005812
Shalaj Jain273b3e02012-06-22 19:08:03 -07005813 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5814 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
5815 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5816 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005817 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005818 streaming[OUTPUT_PORT] = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005819 } else{
5820 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005821 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005822 }
5823}
5824 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5825 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5826 time_stamp_dts.insert_timestamp(buffer);
5827
5828 return ret;
5829}
5830
5831/* ======================================================================
5832FUNCTION
5833 omx_vdec::FillThisBuffer
5834
5835DESCRIPTION
5836 IL client uses this method to release the frame buffer
5837 after displaying them.
5838
5839PARAMETERS
5840 None.
5841
5842RETURN VALUE
5843 true/false
5844
5845========================================================================== */
5846OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5847 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5848{
5849
5850 if(m_state == OMX_StateInvalid)
5851 {
5852 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5853 return OMX_ErrorInvalidState;
5854 }
5855
5856 if (!m_out_bEnabled)
5857 {
5858 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5859 return OMX_ErrorIncorrectStateOperation;
5860 }
5861
Vinay Kaliada4f4422013-01-09 10:45:03 -08005862 if (buffer == NULL ||
5863 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount))
Shalaj Jain273b3e02012-06-22 19:08:03 -07005864 {
5865 return OMX_ErrorBadParameter;
5866 }
5867
5868 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
5869 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08005870 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005871 return OMX_ErrorBadPortIndex;
5872 }
5873
5874 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Vinay Kaliada4f4422013-01-09 10:45:03 -08005875 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005876 return OMX_ErrorNone;
5877}
5878/* ======================================================================
5879FUNCTION
5880 omx_vdec::fill_this_buffer_proxy
5881
5882DESCRIPTION
5883 IL client uses this method to release the frame buffer
5884 after displaying them.
5885
5886PARAMETERS
5887 None.
5888
5889RETURN VALUE
5890 true/false
5891
5892========================================================================== */
5893OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
5894 OMX_IN OMX_HANDLETYPE hComp,
5895 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
5896{
5897 OMX_ERRORTYPE nRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005898 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5899 unsigned nPortIndex = 0;
5900 struct vdec_fillbuffer_cmd fillbuffer;
5901 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5902 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
5903
Vinay Kaliada4f4422013-01-09 10:45:03 -08005904 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005905
Vinay Kaliada4f4422013-01-09 10:45:03 -08005906 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005907 return OMX_ErrorBadParameter;
5908
5909 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5910 bufferAdd, bufferAdd->pBuffer);
5911 /*Return back the output buffer to client*/
5912 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
5913 {
5914 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5915 buffer->nFilledLen = 0;
5916 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5917 return OMX_ErrorNone;
5918 }
5919 pending_output_buffers++;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005920 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005921 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5922 if (ptr_respbuffer)
5923 {
5924 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5925 }
5926
5927 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
5928 {
5929 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5930 buffer->nFilledLen = 0;
5931 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5932 pending_output_buffers--;
5933 return OMX_ErrorBadParameter;
5934 }
5935
Shalaj Jain286b0062013-02-21 20:35:48 -08005936 /* memcpy (&fillbuffer.buffer,ptr_outputbuffer,
Shalaj Jain273b3e02012-06-22 19:08:03 -07005937 sizeof(struct vdec_bufferpayload));
Shalaj Jain286b0062013-02-21 20:35:48 -08005938 fillbuffer.client_data = bufferAdd;*/
Shalaj Jain273b3e02012-06-22 19:08:03 -07005939
5940#ifdef _ANDROID_ICS_
5941 if (m_enable_android_native_buffers)
5942 {
5943 // Acquire a write lock on this buffer.
5944 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
5945 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
5946 DEBUG_PRINT_ERROR("Failed to acquire genlock");
5947 buffer->nFilledLen = 0;
5948 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5949 pending_output_buffers--;
5950 return OMX_ErrorInsufficientResources;
5951 } else {
5952 native_buffer[buffer - m_out_mem_ptr].inuse = true;
5953 }
5954 }
5955#endif
5956 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08005957 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005958 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Praneeth Paladugu32284302013-02-14 22:53:06 -08005959 memset( (void *)&buf, 0, sizeof(buf));
5960 memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005961 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005962
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005963 buf.index = nPortIndex;
5964 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5965 buf.memory = V4L2_MEMORY_USERPTR;
5966 plane[0].bytesused = buffer->nFilledLen;
5967 plane[0].length = drv_ctx.op_buf.buffer_size;
Shalaj Jain286b0062013-02-21 20:35:48 -08005968 plane[0].m.userptr =
5969 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
5970 (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005971 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5972 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5973 plane[0].data_offset = 0;
5974 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5975 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5976 plane[extra_idx].bytesused = 0;
5977 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5978 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
5979#ifdef USE_ION
5980 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5981#endif
5982 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5983 plane[extra_idx].data_offset = 0;
5984 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5985 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5986 return OMX_ErrorBadParameter;
5987 }
5988 buf.m.planes = plane;
5989 buf.length = drv_ctx.num_planes;
5990 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5991 if (rc) {
5992 /*TODO: How to handle this case */
5993 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5994 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005995//#ifdef _ANDROID_ICS_
5996 // if (m_enable_android_native_buffers)
5997 // {
5998 // Unlock the buffer
5999 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6000 // DEBUG_PRINT_ERROR("Releasing genlock failed");
6001 // return OMX_ErrorInsufficientResources;
6002 /// } else {
6003 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
6004 // }
6005 // }
6006//#endif
6007 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
6008 // pending_output_buffers--;
6009 // return OMX_ErrorBadParameter;
6010 //}
6011 return OMX_ErrorNone;
6012}
6013
6014/* ======================================================================
6015FUNCTION
6016 omx_vdec::SetCallbacks
6017
6018DESCRIPTION
6019 Set the callbacks.
6020
6021PARAMETERS
6022 None.
6023
6024RETURN VALUE
6025 OMX Error None if everything successful.
6026
6027========================================================================== */
6028OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
6029 OMX_IN OMX_CALLBACKTYPE* callbacks,
6030 OMX_IN OMX_PTR appData)
6031{
6032
6033 m_cb = *callbacks;
6034 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
6035 m_cb.EventHandler,m_cb.FillBufferDone);
6036 m_app_data = appData;
6037 return OMX_ErrorNotImplemented;
6038}
6039
6040/* ======================================================================
6041FUNCTION
6042 omx_vdec::ComponentDeInit
6043
6044DESCRIPTION
6045 Destroys the component and release memory allocated to the heap.
6046
6047PARAMETERS
6048 <TBD>.
6049
6050RETURN VALUE
6051 OMX Error None if everything successful.
6052
6053========================================================================== */
6054OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6055{
6056#ifdef _ANDROID_
6057 if(iDivXDrmDecrypt)
6058 {
6059 delete iDivXDrmDecrypt;
6060 iDivXDrmDecrypt=NULL;
6061 }
6062#endif //_ANDROID_
6063
Shalaj Jain286b0062013-02-21 20:35:48 -08006064 unsigned i = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006065 if (OMX_StateLoaded != m_state)
6066 {
6067 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
6068 m_state);
6069 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
6070 }
6071 else
6072 {
6073 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
6074 }
6075
6076 /*Check if the output buffers have to be cleaned up*/
6077 if(m_out_mem_ptr)
6078 {
6079 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006080 for (i = 0; i < drv_ctx.op_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006081 {
6082 free_output_buffer (&m_out_mem_ptr[i]);
6083#ifdef _ANDROID_ICS_
6084 if (m_enable_android_native_buffers)
6085 {
6086 if (native_buffer[i].inuse)
6087 {
6088 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
6089 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6090 }
6091 native_buffer[i].inuse = false;
6092 }
6093 }
6094#endif
6095 }
6096#ifdef _ANDROID_ICS_
6097 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6098#endif
6099 }
6100
6101 /*Check if the input buffers have to be cleaned up*/
6102 if(m_inp_mem_ptr || m_inp_heap_ptr)
6103 {
6104 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
Shalaj Jain286b0062013-02-21 20:35:48 -08006105 for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ )
Shalaj Jain273b3e02012-06-22 19:08:03 -07006106 {
6107 if (m_inp_mem_ptr)
6108 free_input_buffer (i,&m_inp_mem_ptr[i]);
6109 else
6110 free_input_buffer (i,NULL);
6111 }
6112 }
6113 free_input_buffer_header();
6114 free_output_buffer_header();
6115 if(h264_scratch.pBuffer)
6116 {
6117 free(h264_scratch.pBuffer);
6118 h264_scratch.pBuffer = NULL;
6119 }
6120
6121 if (h264_parser)
6122 {
6123 delete h264_parser;
6124 h264_parser = NULL;
6125 }
6126
6127 if(m_platform_list)
6128 {
6129 free(m_platform_list);
6130 m_platform_list = NULL;
6131 }
6132 if(m_vendor_config.pData)
6133 {
6134 free(m_vendor_config.pData);
6135 m_vendor_config.pData = NULL;
6136 }
6137
6138 // Reset counters in mesg queues
6139 m_ftb_q.m_size=0;
6140 m_cmd_q.m_size=0;
6141 m_etb_q.m_size=0;
6142 m_ftb_q.m_read = m_ftb_q.m_write =0;
6143 m_cmd_q.m_read = m_cmd_q.m_write =0;
6144 m_etb_q.m_read = m_etb_q.m_write =0;
6145#ifdef _ANDROID_
6146 if (m_debug_timestamp)
6147 {
6148 m_timestamp_list.reset_ts_list();
6149 }
6150#endif
6151
6152 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
6153 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
6154 // NULL);
6155 DEBUG_PRINT_HIGH("\n Close the driver instance");
6156
6157#ifdef INPUT_BUFFER_LOG
6158 fclose (inputBufferFile1);
6159#endif
6160#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006161 if (outputBufferFile1)
6162 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006163#endif
6164#ifdef OUTPUT_EXTRADATA_LOG
6165 fclose (outputExtradataFile);
6166#endif
6167 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
6168 return OMX_ErrorNone;
6169}
6170
6171/* ======================================================================
6172FUNCTION
6173 omx_vdec::UseEGLImage
6174
6175DESCRIPTION
6176 OMX Use EGL Image method implementation <TBD>.
6177
6178PARAMETERS
6179 <TBD>.
6180
6181RETURN VALUE
6182 Not Implemented error.
6183
6184========================================================================== */
6185OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
6186 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6187 OMX_IN OMX_U32 port,
6188 OMX_IN OMX_PTR appData,
6189 OMX_IN void* eglImage)
6190{
6191 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6192 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6193 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
6194
6195#ifdef USE_EGL_IMAGE_GPU
6196 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6197 EGLint fd = -1, offset = 0,pmemPtr = 0;
6198#else
6199 int fd = -1, offset = 0;
6200#endif
6201 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
6202 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
6203 DEBUG_PRINT_ERROR("\n ");
6204 }
6205#ifdef USE_EGL_IMAGE_GPU
6206 if(m_display_id == NULL) {
6207 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
6208 return OMX_ErrorInsufficientResources;
6209 }
6210 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6211 eglGetProcAddress("eglQueryImageKHR");
6212 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6213 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6214 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
6215#else //with OMX test app
6216 struct temp_egl {
6217 int pmem_fd;
6218 int offset;
6219 };
6220 struct temp_egl *temp_egl_id = NULL;
6221 void * pmemPtr = (void *) eglImage;
6222 temp_egl_id = (struct temp_egl *)eglImage;
6223 if (temp_egl_id != NULL)
6224 {
6225 fd = temp_egl_id->pmem_fd;
6226 offset = temp_egl_id->offset;
6227 }
6228#endif
6229 if (fd < 0) {
6230 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
6231 return OMX_ErrorInsufficientResources;
6232 }
6233 pmem_info.pmem_fd = (OMX_U32) fd;
6234 pmem_info.offset = (OMX_U32) offset;
6235 pmem_entry.entry = (void *) &pmem_info;
6236 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6237 pmem_list.entryList = &pmem_entry;
6238 pmem_list.nEntries = 1;
6239 ouput_egl_buffers = true;
6240 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6241 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6242 (OMX_U8 *)pmemPtr)) {
6243 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
6244 return OMX_ErrorInsufficientResources;
6245 }
6246 return OMX_ErrorNone;
6247}
6248
6249/* ======================================================================
6250FUNCTION
6251 omx_vdec::ComponentRoleEnum
6252
6253DESCRIPTION
6254 OMX Component Role Enum method implementation.
6255
6256PARAMETERS
6257 <TBD>.
6258
6259RETURN VALUE
6260 OMX Error None if everything is successful.
6261========================================================================== */
6262OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6263 OMX_OUT OMX_U8* role,
6264 OMX_IN OMX_U32 index)
6265{
6266 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6267
6268 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6269 {
6270 if((0 == index) && role)
6271 {
6272 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6273 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6274 }
6275 else
6276 {
6277 eRet = OMX_ErrorNoMore;
6278 }
6279 }
6280 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6281 {
6282 if((0 == index) && role)
6283 {
6284 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6285 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6286 }
6287 else
6288 {
6289 eRet = OMX_ErrorNoMore;
6290 }
6291 }
6292 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6293 {
6294 if((0 == index) && role)
6295 {
6296 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6297 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6298 }
6299 else
6300 {
6301 DEBUG_PRINT_LOW("\n No more roles \n");
6302 eRet = OMX_ErrorNoMore;
6303 }
6304 }
6305
6306 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6307 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6308 )
6309
6310 {
6311 if((0 == index) && role)
6312 {
6313 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6314 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6315 }
6316 else
6317 {
6318 DEBUG_PRINT_LOW("\n No more roles \n");
6319 eRet = OMX_ErrorNoMore;
6320 }
6321 }
6322 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6323 {
6324 if((0 == index) && role)
6325 {
6326 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6327 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6328 }
6329 else
6330 {
6331 DEBUG_PRINT_LOW("\n No more roles \n");
6332 eRet = OMX_ErrorNoMore;
6333 }
6334 }
6335 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6336 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6337 )
6338 {
6339 if((0 == index) && role)
6340 {
6341 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6342 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6343 }
6344 else
6345 {
6346 DEBUG_PRINT_LOW("\n No more roles \n");
6347 eRet = OMX_ErrorNoMore;
6348 }
6349 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006350 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6351 {
6352 if((0 == index) && role)
6353 {
6354 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6355 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6356 }
6357 else
6358 {
6359 DEBUG_PRINT_LOW("\n No more roles \n");
6360 eRet = OMX_ErrorNoMore;
6361 }
6362 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006363 else
6364 {
6365 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6366 eRet = OMX_ErrorInvalidComponentName;
6367 }
6368 return eRet;
6369}
6370
6371
6372
6373
6374/* ======================================================================
6375FUNCTION
6376 omx_vdec::AllocateDone
6377
6378DESCRIPTION
6379 Checks if entire buffer pool is allocated by IL Client or not.
6380 Need this to move to IDLE state.
6381
6382PARAMETERS
6383 None.
6384
6385RETURN VALUE
6386 true/false.
6387
6388========================================================================== */
6389bool omx_vdec::allocate_done(void)
6390{
6391 bool bRet = false;
6392 bool bRet_In = false;
6393 bool bRet_Out = false;
6394
6395 bRet_In = allocate_input_done();
6396 bRet_Out = allocate_output_done();
6397
6398 if(bRet_In && bRet_Out)
6399 {
6400 bRet = true;
6401 }
6402
6403 return bRet;
6404}
6405/* ======================================================================
6406FUNCTION
6407 omx_vdec::AllocateInputDone
6408
6409DESCRIPTION
6410 Checks if I/P buffer pool is allocated by IL Client or not.
6411
6412PARAMETERS
6413 None.
6414
6415RETURN VALUE
6416 true/false.
6417
6418========================================================================== */
6419bool omx_vdec::allocate_input_done(void)
6420{
6421 bool bRet = false;
6422 unsigned i=0;
6423
6424 if (m_inp_mem_ptr == NULL)
6425 {
6426 return bRet;
6427 }
6428 if(m_inp_mem_ptr )
6429 {
6430 for(;i<drv_ctx.ip_buf.actualcount;i++)
6431 {
6432 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6433 {
6434 break;
6435 }
6436 }
6437 }
6438 if(i == drv_ctx.ip_buf.actualcount)
6439 {
6440 bRet = true;
6441 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6442 }
6443 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6444 {
6445 m_inp_bPopulated = OMX_TRUE;
6446 }
6447 return bRet;
6448}
6449/* ======================================================================
6450FUNCTION
6451 omx_vdec::AllocateOutputDone
6452
6453DESCRIPTION
6454 Checks if entire O/P buffer pool is allocated by IL Client or not.
6455
6456PARAMETERS
6457 None.
6458
6459RETURN VALUE
6460 true/false.
6461
6462========================================================================== */
6463bool omx_vdec::allocate_output_done(void)
6464{
6465 bool bRet = false;
6466 unsigned j=0;
6467
6468 if (m_out_mem_ptr == NULL)
6469 {
6470 return bRet;
6471 }
6472
6473 if (m_out_mem_ptr)
6474 {
6475 for(;j < drv_ctx.op_buf.actualcount;j++)
6476 {
6477 if(BITMASK_ABSENT(&m_out_bm_count,j))
6478 {
6479 break;
6480 }
6481 }
6482 }
6483
6484 if(j == drv_ctx.op_buf.actualcount)
6485 {
6486 bRet = true;
6487 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6488 if(m_out_bEnabled)
6489 m_out_bPopulated = OMX_TRUE;
6490 }
6491
6492 return bRet;
6493}
6494
6495/* ======================================================================
6496FUNCTION
6497 omx_vdec::ReleaseDone
6498
6499DESCRIPTION
6500 Checks if IL client has released all the buffers.
6501
6502PARAMETERS
6503 None.
6504
6505RETURN VALUE
6506 true/false
6507
6508========================================================================== */
6509bool omx_vdec::release_done(void)
6510{
6511 bool bRet = false;
6512
6513 if(release_input_done())
6514 {
6515 if(release_output_done())
6516 {
6517 bRet = true;
6518 }
6519 }
6520 return bRet;
6521}
6522
6523
6524/* ======================================================================
6525FUNCTION
6526 omx_vdec::ReleaseOutputDone
6527
6528DESCRIPTION
6529 Checks if IL client has released all the buffers.
6530
6531PARAMETERS
6532 None.
6533
6534RETURN VALUE
6535 true/false
6536
6537========================================================================== */
6538bool omx_vdec::release_output_done(void)
6539{
6540 bool bRet = false;
6541 unsigned i=0,j=0;
6542
6543 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6544 if(m_out_mem_ptr)
6545 {
6546 for(;j < drv_ctx.op_buf.actualcount ; j++)
6547 {
6548 if(BITMASK_PRESENT(&m_out_bm_count,j))
6549 {
6550 break;
6551 }
6552 }
6553 if(j == drv_ctx.op_buf.actualcount)
6554 {
6555 m_out_bm_count = 0;
6556 bRet = true;
6557 }
6558 }
6559 else
6560 {
6561 m_out_bm_count = 0;
6562 bRet = true;
6563 }
6564 return bRet;
6565}
6566/* ======================================================================
6567FUNCTION
6568 omx_vdec::ReleaseInputDone
6569
6570DESCRIPTION
6571 Checks if IL client has released all the buffers.
6572
6573PARAMETERS
6574 None.
6575
6576RETURN VALUE
6577 true/false
6578
6579========================================================================== */
6580bool omx_vdec::release_input_done(void)
6581{
6582 bool bRet = false;
6583 unsigned i=0,j=0;
6584
6585 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6586 if(m_inp_mem_ptr)
6587 {
6588 for(;j<drv_ctx.ip_buf.actualcount;j++)
6589 {
6590 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6591 {
6592 break;
6593 }
6594 }
6595 if(j==drv_ctx.ip_buf.actualcount)
6596 {
6597 bRet = true;
6598 }
6599 }
6600 else
6601 {
6602 bRet = true;
6603 }
6604 return bRet;
6605}
6606
6607OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6608 OMX_BUFFERHEADERTYPE * buffer)
6609{
6610 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6611 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6612 {
6613 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6614 return OMX_ErrorBadParameter;
6615 }
6616 else if (output_flush_progress)
6617 {
6618 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6619 buffer->nFilledLen = 0;
6620 buffer->nTimeStamp = 0;
6621 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6622 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6623 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6624 }
6625
6626 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6627 buffer, buffer->pBuffer);
6628 pending_output_buffers --;
6629
6630 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6631 {
6632 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6633 if (!output_flush_progress)
Shalaj Jain286b0062013-02-21 20:35:48 -08006634 post_event((unsigned)NULL, (unsigned)NULL,
6635 OMX_COMPONENT_GENERATE_EOS_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006636
6637 if (psource_frame)
6638 {
6639 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6640 psource_frame = NULL;
6641 }
6642 if (pdest_frame)
6643 {
6644 pdest_frame->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006645 m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
6646 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006647 pdest_frame = NULL;
6648 }
6649 }
6650
6651 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6652#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006653 if (outputBufferFile1 && buffer->nFilledLen)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006654 {
Vinay Kalia29beebd2012-10-16 20:06:26 -07006655 int buf_index = buffer - m_out_mem_ptr;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006656 int stride = drv_ctx.video_resolution.stride;
6657 int scanlines = drv_ctx.video_resolution.scan_lines;
6658 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006659 int i;
6660 int bytes_written = 0;
6661 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6662 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6663 temp += stride;
6664 }
6665 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006666 int stride_c = stride;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006667 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6668 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6669 temp += stride_c;
6670 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006671 }
6672#endif
6673
6674 /* For use buffer we need to copy the data */
6675 if (!output_flush_progress)
6676 {
Praneeth Paladugu8f12e822013-03-11 18:47:58 -07006677 /* This is the error check for non-recoverable errros */
6678 if (buffer->nFilledLen > 0)
6679 time_stamp_dts.get_next_timestamp(buffer,
6680 (drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6681 ?true:false);
6682 else {
6683 m_inp_err_count++;
6684 time_stamp_dts.remove_time_stamp(
6685 buffer->nTimeStamp,
6686 (drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6687 ?true:false);
6688 }
Praneeth Paladugu451eec92013-01-31 22:45:45 -08006689 if (m_debug_timestamp)
6690 {
6691 {
6692 OMX_TICKS expected_ts = 0;
6693 m_timestamp_list.pop_min_ts(expected_ts);
6694 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6695 buffer->nTimeStamp, expected_ts);
6696
6697 if (buffer->nTimeStamp != expected_ts)
6698 {
6699 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6700 }
6701 }
6702 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006703 }
6704 if (m_cb.FillBufferDone)
6705 {
6706 if (buffer->nFilledLen > 0)
6707 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006708 handle_extradata(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006709 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6710 // Keep min timestamp interval to handle corrupted bit stream scenario
6711 set_frame_rate(buffer->nTimeStamp);
6712 else if (arbitrary_bytes)
6713 adjust_timestamp(buffer->nTimeStamp);
6714 if (perf_flag)
6715 {
6716 if (!proc_frms)
6717 {
6718 dec_time.stop();
6719 latency = dec_time.processing_time_us() - latency;
6720 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6721 dec_time.start();
6722 fps_metrics.start();
6723 }
6724 proc_frms++;
6725 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6726 {
6727 OMX_U64 proc_time = 0;
6728 fps_metrics.stop();
6729 proc_time = fps_metrics.processing_time_us();
6730 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6731 proc_frms, (float)proc_time / 1e6,
6732 (float)(1e6 * proc_frms) / proc_time);
6733 proc_frms = 0;
6734 }
6735 }
6736
6737#ifdef OUTPUT_EXTRADATA_LOG
6738 if (outputExtradataFile)
6739 {
6740
6741 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6742 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6743 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6744 buffer->nFilledLen + 3)&(~3));
6745 while(p_extra &&
6746 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
6747 {
6748 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6749 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6750 if (p_extra->eType == OMX_ExtraDataNone)
6751 {
6752 break;
6753 }
6754 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6755 }
6756 }
6757#endif
6758 }
6759 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
6760 prev_ts = LLONG_MAX;
6761 rst_prev_ts = true;
6762 }
6763
6764 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6765 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6766 buffer->pPlatformPrivate)->entryList->entry;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006767 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006768#ifdef _ANDROID_ICS_
6769 if (m_enable_android_native_buffers)
6770 {
6771 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6772 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6773 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6774 return OMX_ErrorInsufficientResources;
6775 }
6776 else {
6777 native_buffer[buffer - m_out_mem_ptr].inuse = false;
6778 }
6779 }
6780 }
6781#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -08006782 OMX_BUFFERHEADERTYPE *il_buffer;
6783 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6784 if (il_buffer)
6785 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6786 else {
6787 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6788 return OMX_ErrorBadParameter;
6789 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07006790 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006791 }
6792 else
6793 {
6794 return OMX_ErrorBadParameter;
6795 }
6796
6797 return OMX_ErrorNone;
6798}
6799
6800OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
6801 OMX_BUFFERHEADERTYPE* buffer)
6802{
6803
6804 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
6805 {
6806 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
6807 return OMX_ErrorBadParameter;
6808 }
6809
6810 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6811 buffer, buffer->pBuffer);
6812 pending_input_buffers--;
6813
6814 if (arbitrary_bytes)
6815 {
6816 if (pdest_frame == NULL && input_flush_progress == false)
6817 {
6818 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6819 pdest_frame = buffer;
6820 buffer->nFilledLen = 0;
6821 buffer->nTimeStamp = LLONG_MAX;
6822 push_input_buffer (hComp);
6823 }
6824 else
6825 {
6826 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6827 buffer->nFilledLen = 0;
Shalaj Jain286b0062013-02-21 20:35:48 -08006828 if (!m_input_free_q.insert_entry((unsigned)buffer,
6829 (unsigned)NULL, (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07006830 {
6831 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6832 }
6833 }
6834 }
6835 else if(m_cb.EmptyBufferDone)
6836 {
6837 buffer->nFilledLen = 0;
6838 if (input_use_buffer == true){
6839 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6840 }
6841 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6842 }
6843 return OMX_ErrorNone;
6844}
6845
Shalaj Jain273b3e02012-06-22 19:08:03 -07006846int omx_vdec::async_message_process (void *context, void* message)
6847{
6848 omx_vdec* omx = NULL;
6849 struct vdec_msginfo *vdec_msg = NULL;
6850 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08006851 struct v4l2_buffer *v4l2_buf_ptr = NULL;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006852 struct vdec_output_frameinfo *output_respbuf = NULL;
6853 int rc=1;
6854 if (context == NULL || message == NULL)
6855 {
6856 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6857 return -1;
6858 }
6859 vdec_msg = (struct vdec_msginfo *)message;
6860
6861 omx = reinterpret_cast<omx_vdec*>(context);
6862
Shalaj Jain273b3e02012-06-22 19:08:03 -07006863 switch (vdec_msg->msgcode)
6864 {
6865
6866 case VDEC_MSG_EVT_HW_ERROR:
Shalaj Jain286b0062013-02-21 20:35:48 -08006867 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006868 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6869 break;
6870
6871 case VDEC_MSG_RESP_START_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006872 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006873 OMX_COMPONENT_GENERATE_START_DONE);
6874 break;
6875
6876 case VDEC_MSG_RESP_STOP_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006877 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006878 OMX_COMPONENT_GENERATE_STOP_DONE);
6879 break;
6880
6881 case VDEC_MSG_RESP_RESUME_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006882 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006883 OMX_COMPONENT_GENERATE_RESUME_DONE);
6884 break;
6885
6886 case VDEC_MSG_RESP_PAUSE_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006887 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006888 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6889 break;
6890
6891 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006892 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006893 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6894 break;
6895 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
Shalaj Jain286b0062013-02-21 20:35:48 -08006896 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
Shalaj Jain273b3e02012-06-22 19:08:03 -07006897 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6898 break;
6899 case VDEC_MSG_RESP_INPUT_FLUSHED:
6900 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6901
Shalaj Jain286b0062013-02-21 20:35:48 -08006902 /* omxhdr = (OMX_BUFFERHEADERTYPE* )
6903 vdec_msg->msgdata.input_frame_clientdata; */
Shalaj Jain273b3e02012-06-22 19:08:03 -07006904
6905 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6906 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6907 if (omxhdr == NULL ||
6908 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
6909 {
6910 omxhdr = NULL;
6911 vdec_msg->status_code = VDEC_S_EFATAL;
6912 }
6913
6914 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6915 OMX_COMPONENT_GENERATE_EBD);
6916 break;
6917 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6918 int64_t *timestamp;
6919 timestamp = (int64_t *) malloc(sizeof(int64_t));
6920 if (timestamp) {
6921 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6922 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6923 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6924 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6925 vdec_msg->msgdata.output_frame.time_stamp);
6926 }
6927 break;
6928 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6929 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6930
6931 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6932 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6933 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6934 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6935 vdec_msg->msgdata.output_frame.pic_type);
6936
6937 if (omxhdr && omxhdr->pOutputPortPrivate &&
6938 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6939 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6940 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
6941 {
6942 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
6943 {
6944 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6945 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07006946 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006947 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
6948
6949 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
6950 {
6951 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6952 //rc = -1;
6953 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08006954 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ)
6955 {
6956 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6957 }
Shalaj Jain286b0062013-02-21 20:35:48 -08006958 vdec_msg->msgdata.output_frame.bufferaddr =
6959 omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6960 if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
6961 vdec_msg->msgdata.output_frame.framesize.left)
6962 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
Vinay Kalia592e4b42012-12-19 15:55:47 -08006963 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6964 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6965 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6966 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6967 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6968 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6969 DEBUG_PRINT_HIGH("\n Crop information has changed\n");
6970 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6971 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6972 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006973 output_respbuf = (struct vdec_output_frameinfo *)\
6974 omxhdr->pOutputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006975 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6976 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08006977 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME)
6978 {
6979 output_respbuf->pic_type = PICTURE_TYPE_I;
6980 }
6981 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME)
6982 {
6983 output_respbuf->pic_type = PICTURE_TYPE_P;
6984 }
6985 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6986 output_respbuf->pic_type = PICTURE_TYPE_B;
6987 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006988
6989 if (omx->output_use_buffer)
Shalaj Jain286b0062013-02-21 20:35:48 -08006990 memcpy ( omxhdr->pBuffer, (void *)
6991 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
6992 (unsigned long)vdec_msg->msgdata.output_frame.offset),
6993 vdec_msg->msgdata.output_frame.len);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006994 }
6995 else
6996 omxhdr->nFilledLen = 0;
6997 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6998 OMX_COMPONENT_GENERATE_FBD);
6999 }
7000 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
Shalaj Jain286b0062013-02-21 20:35:48 -08007001 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007002 OMX_COMPONENT_GENERATE_EOS_DONE);
7003 else
Shalaj Jain286b0062013-02-21 20:35:48 -08007004 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007005 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7006 break;
7007 case VDEC_MSG_EVT_CONFIG_CHANGED:
7008 DEBUG_PRINT_HIGH("\n Port settings changed");
Vinay Kalia592e4b42012-12-19 15:55:47 -08007009 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7010 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007011 break;
7012 case VDEC_MSG_EVT_INFO_CONFIG_CHANGED:
7013 {
7014 DEBUG_PRINT_HIGH("\n Port settings changed info");
7015 // get_buffer_req and populate port defn structure
7016 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07007017 struct v4l2_format fmt;
7018 int ret;
7019 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7020 ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
Vinay Kalia592e4b42012-12-19 15:55:47 -08007021 omx->update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height);
Arun Menon6836ba02013-02-19 20:37:40 -08007022 ret = omx->is_video_session_supported();
7023 if (ret) {
7024 omx->post_event (NULL, vdec_msg->status_code,
7025 OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
7026 }
7027 else {
7028 omx->drv_ctx.video_resolution.stride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
7029 omx->drv_ctx.video_resolution.scan_lines = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
7030 omx->m_port_def.nPortIndex = 1;
7031 eRet = omx->update_portdef(&(omx->m_port_def));
7032 omx->post_event ((unsigned)NULL,vdec_msg->status_code,\
7033 OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG);
7034 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007035 break;
7036 }
7037 default:
7038 break;
7039 }
7040 return rc;
7041}
7042
7043OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
7044 OMX_HANDLETYPE hComp,
7045 OMX_BUFFERHEADERTYPE *buffer
7046 )
7047{
7048 unsigned address,p2,id;
7049 DEBUG_PRINT_LOW("\n Empty this arbitrary");
7050
7051 if (buffer == NULL)
7052 {
7053 return OMX_ErrorBadParameter;
7054 }
7055 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007056 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
7057 buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007058
7059 /* return zero length and not an EOS buffer */
7060 /* return buffer if input flush in progress */
7061 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7062 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
7063 {
7064 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
7065 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7066 return OMX_ErrorNone;
7067 }
7068
7069 if (psource_frame == NULL)
7070 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007071 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007072 psource_frame = buffer;
7073 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
7074 push_input_buffer (hComp);
7075 }
7076 else
7077 {
7078 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
Shalaj Jain286b0062013-02-21 20:35:48 -08007079 if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
7080 (unsigned)NULL))
Shalaj Jain273b3e02012-06-22 19:08:03 -07007081 {
7082 return OMX_ErrorBadParameter;
7083 }
7084 }
7085
7086
7087 return OMX_ErrorNone;
7088}
7089
7090OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7091{
7092 unsigned address,p2,id;
7093 OMX_ERRORTYPE ret = OMX_ErrorNone;
7094
7095 if (pdest_frame == NULL || psource_frame == NULL)
7096 {
7097 /*Check if we have a destination buffer*/
7098 if (pdest_frame == NULL)
7099 {
7100 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
7101 if (m_input_free_q.m_size)
7102 {
7103 m_input_free_q.pop_entry(&address,&p2,&id);
7104 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7105 pdest_frame->nFilledLen = 0;
7106 pdest_frame->nTimeStamp = LLONG_MAX;
7107 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
7108 }
7109 }
7110
7111 /*Check if we have a destination buffer*/
7112 if (psource_frame == NULL)
7113 {
7114 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
7115 if (m_input_pending_q.m_size)
7116 {
7117 m_input_pending_q.pop_entry(&address,&p2,&id);
7118 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007119 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007120 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007121 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007122 psource_frame->nFlags,psource_frame->nFilledLen);
7123
7124 }
7125 }
7126
7127 }
7128
7129 while ((pdest_frame != NULL) && (psource_frame != NULL))
7130 {
7131 switch (codec_type_parse)
7132 {
7133 case CODEC_TYPE_MPEG4:
7134 case CODEC_TYPE_H263:
7135 case CODEC_TYPE_MPEG2:
7136 ret = push_input_sc_codec(hComp);
7137 break;
7138 case CODEC_TYPE_H264:
7139 ret = push_input_h264(hComp);
7140 break;
7141 case CODEC_TYPE_VC1:
7142 ret = push_input_vc1(hComp);
7143 break;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007144 default:
7145 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007146 }
7147 if (ret != OMX_ErrorNone)
7148 {
7149 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
7150 omx_report_error ();
7151 break;
7152 }
7153 }
7154
7155 return ret;
7156}
7157
7158OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7159{
7160 OMX_U32 partial_frame = 1;
7161 OMX_BOOL generate_ebd = OMX_TRUE;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007162 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007163
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007164 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007165 psource_frame,psource_frame->nTimeStamp);
7166 if (m_frame_parser.parse_sc_frame(psource_frame,
7167 pdest_frame,&partial_frame) == -1)
7168 {
7169 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7170 return OMX_ErrorBadParameter;
7171 }
7172
7173 if (partial_frame == 0)
7174 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007175 DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007176 pdest_frame->nFilledLen,psource_frame,frame_count);
7177
7178
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007179 DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007180 /*First Parsed buffer will have only header Hence skip*/
7181 if (frame_count == 0)
7182 {
7183 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
7184
7185 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
7186 codec_type_parse == CODEC_TYPE_DIVX) {
7187 mp4StreamType psBits;
7188 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7189 psBits.numBytes = pdest_frame->nFilledLen;
7190 mp4_headerparser.parseHeader(&psBits);
7191 }
7192
7193 frame_count++;
7194 }
7195 else
7196 {
7197 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7198 if(pdest_frame->nFilledLen)
7199 {
7200 /*Push the frame to the Decoder*/
7201 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7202 {
7203 return OMX_ErrorBadParameter;
7204 }
7205 frame_count++;
7206 pdest_frame = NULL;
7207
7208 if (m_input_free_q.m_size)
7209 {
7210 m_input_free_q.pop_entry(&address,&p2,&id);
7211 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7212 pdest_frame->nFilledLen = 0;
7213 }
7214 }
7215 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
7216 {
7217 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
Shalaj Jain286b0062013-02-21 20:35:48 -08007218 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
7219 (unsigned)NULL);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007220 pdest_frame = NULL;
7221 }
7222 }
7223 }
7224 else
7225 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007226 DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007227 /*Check if Destination Buffer is full*/
7228 if (pdest_frame->nAllocLen ==
7229 pdest_frame->nFilledLen + pdest_frame->nOffset)
7230 {
7231 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
7232 return OMX_ErrorStreamCorrupt;
7233 }
7234 }
7235
7236 if (psource_frame->nFilledLen == 0)
7237 {
7238 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7239 {
7240 if (pdest_frame)
7241 {
7242 pdest_frame->nFlags |= psource_frame->nFlags;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007243 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007244 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007245 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007246 pdest_frame->nFilledLen,frame_count++);
7247 /*Push the frame to the Decoder*/
7248 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7249 {
7250 return OMX_ErrorBadParameter;
7251 }
7252 frame_count++;
7253 pdest_frame = NULL;
7254 }
7255 else
7256 {
7257 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
7258 generate_ebd = OMX_FALSE;
7259 }
7260 }
7261 if(generate_ebd)
7262 {
7263 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
7264 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7265 psource_frame = NULL;
7266
7267 if (m_input_pending_q.m_size)
7268 {
7269 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7270 m_input_pending_q.pop_entry(&address,&p2,&id);
7271 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007272 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
Shalaj Jain273b3e02012-06-22 19:08:03 -07007273 psource_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007274 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007275 psource_frame->nFlags,psource_frame->nFilledLen);
7276 }
7277 }
7278 }
7279 return OMX_ErrorNone;
7280}
7281
7282OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7283{
7284 OMX_U32 partial_frame = 1;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007285 unsigned address = 0, p2 = 0, id = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007286 OMX_BOOL isNewFrame = OMX_FALSE;
7287 OMX_BOOL generate_ebd = OMX_TRUE;
7288
7289 if (h264_scratch.pBuffer == NULL)
7290 {
7291 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7292 return OMX_ErrorBadParameter;
7293 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007294 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
Shalaj Jain273b3e02012-06-22 19:08:03 -07007295 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007296 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007297 if (h264_scratch.nFilledLen && look_ahead_nal)
7298 {
7299 look_ahead_nal = false;
7300 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7301 h264_scratch.nFilledLen)
7302 {
7303 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7304 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7305 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7306 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7307 h264_scratch.nFilledLen = 0;
7308 }
7309 else
7310 {
7311 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7312 return OMX_ErrorBadParameter;
7313 }
7314 }
7315 if (nal_length == 0)
7316 {
7317 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7318 if (m_frame_parser.parse_sc_frame(psource_frame,
7319 &h264_scratch,&partial_frame) == -1)
7320 {
7321 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7322 return OMX_ErrorBadParameter;
7323 }
7324 }
7325 else
7326 {
7327 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7328 if (m_frame_parser.parse_h264_nallength(psource_frame,
7329 &h264_scratch,&partial_frame) == -1)
7330 {
7331 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7332 return OMX_ErrorBadParameter;
7333 }
7334 }
7335
7336 if (partial_frame == 0)
7337 {
7338 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7339 {
7340 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7341 nal_count++;
7342 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7343 h264_scratch.nFlags = psource_frame->nFlags;
7344 }
7345 else
7346 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007347 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007348 if(h264_scratch.nFilledLen)
7349 {
7350 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7351 NALU_TYPE_SPS);
7352#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7353 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7354 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7355 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7356 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7357 // If timeinfo is present frame info from SEI is already processed
7358 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7359 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7360#endif
7361 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7362 nal_count++;
7363 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7364 pdest_frame->nTimeStamp = h264_last_au_ts;
7365 pdest_frame->nFlags = h264_last_au_flags;
7366#ifdef PANSCAN_HDLR
7367 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7368 h264_parser->update_panscan_data(h264_last_au_ts);
7369#endif
7370 }
7371 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7372 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7373 h264_last_au_ts = h264_scratch.nTimeStamp;
7374 h264_last_au_flags = h264_scratch.nFlags;
7375#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7376 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7377 {
7378 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7379 if (!VALID_TS(h264_last_au_ts))
7380 h264_last_au_ts = ts_in_sei;
7381 }
7382#endif
7383 } else
7384 h264_last_au_ts = LLONG_MAX;
7385 }
7386
7387 if (!isNewFrame)
7388 {
7389 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7390 h264_scratch.nFilledLen)
7391 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007392 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007393 h264_scratch.nFilledLen);
7394 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7395 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7396 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7397 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7398 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7399 h264_scratch.nFilledLen = 0;
7400 }
7401 else
7402 {
7403 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7404 return OMX_ErrorBadParameter;
7405 }
7406 }
7407 else
7408 {
7409 look_ahead_nal = true;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007410 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007411 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007412 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007413 pdest_frame->nFilledLen,frame_count++);
7414
7415 if (pdest_frame->nFilledLen == 0)
7416 {
7417 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7418 look_ahead_nal = false;
7419 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7420 h264_scratch.nFilledLen)
7421 {
7422 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7423 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7424 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7425 h264_scratch.nFilledLen = 0;
7426 }
7427 else
7428 {
7429 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7430 return OMX_ErrorBadParameter;
7431 }
7432 }
7433 else
7434 {
7435 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7436 {
7437 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7438 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7439 }
7440 /*Push the frame to the Decoder*/
7441 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7442 {
7443 return OMX_ErrorBadParameter;
7444 }
7445 //frame_count++;
7446 pdest_frame = NULL;
7447 if (m_input_free_q.m_size)
7448 {
7449 m_input_free_q.pop_entry(&address,&p2,&id);
7450 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7451 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7452 pdest_frame->nFilledLen = 0;
7453 pdest_frame->nFlags = 0;
7454 pdest_frame->nTimeStamp = LLONG_MAX;
7455 }
7456 }
7457 }
7458 }
7459 }
7460 else
7461 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007462 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007463 /*Check if Destination Buffer is full*/
7464 if (h264_scratch.nAllocLen ==
7465 h264_scratch.nFilledLen + h264_scratch.nOffset)
7466 {
7467 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7468 return OMX_ErrorStreamCorrupt;
7469 }
7470 }
7471
7472 if (!psource_frame->nFilledLen)
7473 {
7474 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7475
7476 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7477 {
7478 if (pdest_frame)
7479 {
7480 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7481 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7482 h264_scratch.nFilledLen)
7483 {
7484 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7485 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7486 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7487 h264_scratch.nFilledLen = 0;
7488 }
7489 else
7490 {
7491 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7492 return OMX_ErrorBadParameter;
7493 }
7494 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7495 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7496
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007497 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007498 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7499 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7500#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7501 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7502 {
7503 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7504 if (!VALID_TS(pdest_frame->nTimeStamp))
7505 pdest_frame->nTimeStamp = ts_in_sei;
7506 }
7507#endif
7508 /*Push the frame to the Decoder*/
7509 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7510 {
7511 return OMX_ErrorBadParameter;
7512 }
7513 frame_count++;
7514 pdest_frame = NULL;
7515 }
7516 else
7517 {
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007518 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007519 pdest_frame,h264_scratch.nFilledLen);
7520 generate_ebd = OMX_FALSE;
7521 }
7522 }
7523 }
7524 if(generate_ebd && !psource_frame->nFilledLen)
7525 {
7526 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7527 psource_frame = NULL;
7528 if (m_input_pending_q.m_size)
7529 {
7530 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7531 m_input_pending_q.pop_entry(&address,&p2,&id);
7532 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07007533 DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
Shalaj Jain273b3e02012-06-22 19:08:03 -07007534 psource_frame->nFlags,psource_frame->nFilledLen);
7535 }
7536 }
7537 return OMX_ErrorNone;
7538}
7539
7540OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7541{
7542 OMX_U8 *buf, *pdest;
7543 OMX_U32 partial_frame = 1;
7544 OMX_U32 buf_len, dest_len;
7545
7546 if(first_frame == 0)
7547 {
7548 first_frame = 1;
7549 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7550 if(!m_vendor_config.pData)
7551 {
7552 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7553 buf = psource_frame->pBuffer;
7554 buf_len = psource_frame->nFilledLen;
7555
7556 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7557 VC1_SP_MP_START_CODE)
7558 {
7559 m_vc1_profile = VC1_SP_MP_RCV;
7560 }
7561 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7562 {
7563 m_vc1_profile = VC1_AP;
7564 }
7565 else
7566 {
7567 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7568 return OMX_ErrorStreamCorrupt;
7569 }
7570 }
7571 else
7572 {
7573 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7574 pdest_frame->nOffset;
7575 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7576 pdest_frame->nOffset);
7577
7578 if(dest_len < m_vendor_config.nDataSize)
7579 {
7580 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7581 return OMX_ErrorBadParameter;
7582 }
7583 else
7584 {
7585 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7586 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7587 }
7588 }
7589 }
7590
7591 switch(m_vc1_profile)
7592 {
7593 case VC1_AP:
7594 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7595 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7596 {
7597 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7598 return OMX_ErrorBadParameter;
7599 }
7600 break;
7601
7602 case VC1_SP_MP_RCV:
7603 default:
7604 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7605 return OMX_ErrorBadParameter;
7606 }
7607 return OMX_ErrorNone;
7608}
7609
David Ng38e2d232013-03-15 20:05:58 -07007610#ifndef USE_ION
Shalaj Jain273b3e02012-06-22 19:08:03 -07007611bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7612 OMX_U32 alignment)
7613{
7614 struct pmem_allocation allocation;
7615 allocation.size = buffer_size;
7616 allocation.align = clip2(alignment);
7617 if (allocation.align < 4096)
7618 {
7619 allocation.align = 4096;
7620 }
7621 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7622 {
7623 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7624 allocation.align, allocation.size);
7625 return false;
7626 }
7627 return true;
7628}
David Ng38e2d232013-03-15 20:05:58 -07007629#endif
Shalaj Jain273b3e02012-06-22 19:08:03 -07007630#ifdef USE_ION
7631int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7632 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7633 struct ion_fd_data *fd_data, int flag)
7634{
7635 int fd = -EINVAL;
7636 int rc = -EINVAL;
7637 int ion_dev_flag;
7638 struct vdec_ion ion_buf_info;
7639 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7640 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7641 return -EINVAL;
7642 }
Arun Menon737de532012-09-14 14:48:18 -07007643 ion_dev_flag = O_RDONLY;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007644 fd = open (MEM_DEVICE, ion_dev_flag);
7645 if (fd < 0) {
7646 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7647 return fd;
7648 }
Arun Menon737de532012-09-14 14:48:18 -07007649 alloc_data->flags = 0;
7650 if(!secure_mode && (flag & ION_FLAG_CACHED))
7651 {
7652 alloc_data->flags |= ION_FLAG_CACHED;
7653 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007654 alloc_data->len = buffer_size;
7655 alloc_data->align = clip2(alignment);
7656 if (alloc_data->align < 4096)
7657 {
7658 alloc_data->align = 4096;
7659 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07007660 if ((secure_mode) && (flag & ION_SECURE))
7661 alloc_data->flags |= ION_SECURE;
7662
Shalaj Jain5af07fb2013-03-07 11:38:41 -08007663 alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7664 if (secure_mode)
7665 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007666 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7667 if (rc || !alloc_data->handle) {
7668 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7669 alloc_data->handle = NULL;
7670 close(fd);
7671 fd = -ENOMEM;
7672 return fd;
7673 }
7674 fd_data->handle = alloc_data->handle;
7675 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7676 if (rc) {
7677 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7678 ion_buf_info.ion_alloc_data = *alloc_data;
7679 ion_buf_info.ion_device_fd = fd;
7680 ion_buf_info.fd_ion_data = *fd_data;
7681 free_ion_memory(&ion_buf_info);
7682 fd_data->fd =-1;
7683 close(fd);
7684 fd = -ENOMEM;
7685 }
7686
7687 return fd;
7688}
7689
7690void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
7691
7692 if(!buf_ion_info) {
7693 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7694 return;
7695 }
7696 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7697 &buf_ion_info->ion_alloc_data.handle)) {
7698 DEBUG_PRINT_ERROR("\n ION: free failed" );
7699 }
7700 close(buf_ion_info->ion_device_fd);
7701 buf_ion_info->ion_device_fd = -1;
7702 buf_ion_info->ion_alloc_data.handle = NULL;
7703 buf_ion_info->fd_ion_data.fd = -1;
7704}
7705#endif
7706void omx_vdec::free_output_buffer_header()
7707{
7708 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7709 output_use_buffer = false;
7710 ouput_egl_buffers = false;
7711
7712 if (m_out_mem_ptr)
7713 {
7714 free (m_out_mem_ptr);
7715 m_out_mem_ptr = NULL;
7716 }
7717
7718 if(m_platform_list)
7719 {
7720 free(m_platform_list);
7721 m_platform_list = NULL;
7722 }
7723
7724 if (drv_ctx.ptr_respbuffer)
7725 {
7726 free (drv_ctx.ptr_respbuffer);
7727 drv_ctx.ptr_respbuffer = NULL;
7728 }
7729 if (drv_ctx.ptr_outputbuffer)
7730 {
7731 free (drv_ctx.ptr_outputbuffer);
7732 drv_ctx.ptr_outputbuffer = NULL;
7733 }
7734#ifdef USE_ION
7735 if (drv_ctx.op_buf_ion_info) {
7736 DEBUG_PRINT_LOW("\n Free o/p ion context");
7737 free(drv_ctx.op_buf_ion_info);
7738 drv_ctx.op_buf_ion_info = NULL;
7739 }
7740#endif
7741}
7742
7743void omx_vdec::free_input_buffer_header()
7744{
7745 input_use_buffer = false;
7746 if (arbitrary_bytes)
7747 {
7748 if (m_frame_parser.mutils)
7749 {
7750 DEBUG_PRINT_LOW("\n Free utils parser");
7751 delete (m_frame_parser.mutils);
7752 m_frame_parser.mutils = NULL;
7753 }
7754
7755 if (m_inp_heap_ptr)
7756 {
7757 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7758 free (m_inp_heap_ptr);
7759 m_inp_heap_ptr = NULL;
7760 }
7761
7762 if (m_phdr_pmem_ptr)
7763 {
7764 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7765 free (m_phdr_pmem_ptr);
7766 m_phdr_pmem_ptr = NULL;
7767 }
7768 }
7769 if (m_inp_mem_ptr)
7770 {
7771 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7772 free (m_inp_mem_ptr);
7773 m_inp_mem_ptr = NULL;
7774 }
7775 if (drv_ctx.ptr_inputbuffer)
7776 {
7777 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7778 free (drv_ctx.ptr_inputbuffer);
7779 drv_ctx.ptr_inputbuffer = NULL;
7780 }
7781#ifdef USE_ION
7782 if (drv_ctx.ip_buf_ion_info) {
7783 DEBUG_PRINT_LOW("\n Free ion context");
7784 free(drv_ctx.ip_buf_ion_info);
7785 drv_ctx.ip_buf_ion_info = NULL;
7786 }
7787#endif
7788}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007789
7790int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007791{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007792 enum v4l2_buf_type btype;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007793 int rc = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007794 enum v4l2_ports v4l2_port = OUTPUT_PORT;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007795
7796 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7797 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7798 v4l2_port = OUTPUT_PORT;
7799 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7800 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7801 v4l2_port = CAPTURE_PORT;
7802 } else if (port == OMX_ALL) {
7803 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7804 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
7805
7806 if (!rc_input)
7807 return rc_input;
7808 else
7809 return rc_output;
7810 }
7811
7812 if (!streaming[v4l2_port]) {
7813 // already streamed off, warn and move on
7814 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7815 " which is already streamed off", v4l2_port);
7816 return 0;
7817 }
7818
7819 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
7820
Shalaj Jain273b3e02012-06-22 19:08:03 -07007821 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7822 if (rc) {
7823 /*TODO: How to handle this case */
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007824 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007825 } else {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007826 streaming[v4l2_port] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007827 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007828
7829 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007830}
7831
7832OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7833{
7834 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7835 struct v4l2_requestbuffers bufreq;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007836 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007837 struct v4l2_format fmt;
Praneeth Paladugu32284302013-02-14 22:53:06 -08007838 int ret = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007839 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7840 buffer_prop->actualcount, buffer_prop->buffer_size);
7841 bufreq.memory = V4L2_MEMORY_USERPTR;
Praneeth Paladugue3337f62012-10-16 17:35:59 -07007842 bufreq.count = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007843 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7844 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7845 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7846 fmt.fmt.pix_mp.pixelformat = output_capability;
7847 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
7848 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7849 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7850 fmt.fmt.pix_mp.pixelformat = capture_capability;
7851 }else {eRet = OMX_ErrorBadParameter;}
7852 if(eRet==OMX_ErrorNone){
7853 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7854 }
7855 if(ret)
7856 {
7857 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7858 /*TODO: How to handle this case */
7859 eRet = OMX_ErrorInsufficientResources;
7860 return eRet;
7861 }
7862 else
7863 {
7864 buffer_prop->actualcount = bufreq.count;
7865 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007866 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007867 }
7868 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7869 buffer_prop->actualcount, buffer_prop->buffer_size);
7870
7871 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7872 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7873
7874 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7875
Vinay Kalia592e4b42012-12-19 15:55:47 -08007876 update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height);
Vinay Kalia5713bb32013-01-16 18:39:59 -08007877 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7878 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007879 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007880
7881 if(ret)
7882 {
7883 /*TODO: How to handle this case */
7884 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7885 eRet = OMX_ErrorInsufficientResources;
7886 }
7887 else
7888 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007889 int extra_idx = 0;
Arun Menon6836ba02013-02-19 20:37:40 -08007890
7891 eRet = is_video_session_supported();
7892 if (eRet)
7893 return eRet;
7894
Shalaj Jain273b3e02012-06-22 19:08:03 -07007895 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7896 buf_size = buffer_prop->buffer_size;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007897 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7898 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7899 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7900 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7901 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7902 return OMX_ErrorBadParameter;
7903 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007904 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7905 {
7906 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007907 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007908 }
7909 if (client_extradata & OMX_INTERLACE_EXTRADATA)
7910 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007911 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007912 }
7913 if (client_extradata & OMX_PORTDEF_EXTRADATA)
7914 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007915 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7916 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7917 client_extra_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007918 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007919 if (client_extra_data_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007920 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007921 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
Shalaj Jain273b3e02012-06-22 19:08:03 -07007922 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7923 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007924 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7925 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7926 drv_ctx.extradata_info.buffer_size = extra_data_size;
7927 buf_size += client_extra_data_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007928 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7929 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007930 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007931 if (in_reconfig) // BufReq will be set to driver when port is disabled
7932 buffer_prop->buffer_size = buf_size;
7933 else if (buf_size != buffer_prop->buffer_size)
7934 {
7935 buffer_prop->buffer_size = buf_size;
7936 eRet = set_buffer_req(buffer_prop);
7937 }
7938 }
7939 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7940 buffer_prop->actualcount, buffer_prop->buffer_size);
7941 return eRet;
7942}
7943
7944OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7945{
7946 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7947 unsigned buf_size = 0;
7948 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007949 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007950 int ret;
7951 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7952 buffer_prop->actualcount, buffer_prop->buffer_size);
7953 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7954 if (buf_size != buffer_prop->buffer_size)
7955 {
7956 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7957 buffer_prop->buffer_size, buf_size);
7958 eRet = OMX_ErrorBadParameter;
7959 }
7960 else
7961 {
7962 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7963 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007964
7965 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7966 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7967 fmt.fmt.pix_mp.pixelformat = output_capability;
7968 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7969 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7970 fmt.fmt.pix_mp.pixelformat = capture_capability;
7971 } else {eRet = OMX_ErrorBadParameter;}
7972
7973 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7974 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007975 {
7976 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007977 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007978 eRet = OMX_ErrorInsufficientResources;
7979 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007980
7981 bufreq.memory = V4L2_MEMORY_USERPTR;
7982 bufreq.count = buffer_prop->actualcount;
7983 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7984 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7985 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7986 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7987 } else {eRet = OMX_ErrorBadParameter;}
7988
7989 if (eRet==OMX_ErrorNone) {
7990 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7991 }
7992
7993 if (ret)
7994 {
7995 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7996 /*TODO: How to handle this case */
7997 eRet = OMX_ErrorInsufficientResources;
7998 } else if (bufreq.count < buffer_prop->actualcount) {
7999 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
8000 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
8001 buffer_prop->actualcount, bufreq.count);
8002 eRet = OMX_ErrorInsufficientResources;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008003 } else {
8004 if (!client_buffers.update_buffer_req()) {
8005 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
8006 eRet = OMX_ErrorInsufficientResources;
8007 }
8008 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008009 }
8010 return eRet;
8011}
8012
Shalaj Jain273b3e02012-06-22 19:08:03 -07008013OMX_ERRORTYPE omx_vdec::update_picture_resolution()
8014{
Shalaj Jain273b3e02012-06-22 19:08:03 -07008015 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008016 return eRet;
8017}
8018
8019OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8020{
8021 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8022 if (!portDefn)
8023 {
8024 return OMX_ErrorBadParameter;
8025 }
8026 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
8027 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8028 portDefn->nSize = sizeof(portDefn);
8029 portDefn->eDomain = OMX_PortDomainVideo;
8030 if (drv_ctx.frame_rate.fps_denominator > 0)
8031 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
8032 drv_ctx.frame_rate.fps_denominator;
8033 else {
8034 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
8035 return OMX_ErrorBadParameter;
8036 }
8037 if (0 == portDefn->nPortIndex)
8038 {
8039 portDefn->eDir = OMX_DirInput;
8040 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8041 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8042 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8043 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8044 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8045 portDefn->bEnabled = m_inp_bEnabled;
8046 portDefn->bPopulated = m_inp_bPopulated;
8047 }
8048 else if (1 == portDefn->nPortIndex)
8049 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008050 unsigned int buf_size = 0;
8051 if (!client_buffers.update_buffer_req()) {
8052 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
8053 return OMX_ErrorHardware;
8054 }
8055 if (!client_buffers.get_buffer_req(buf_size)) {
8056 DEBUG_PRINT_ERROR("\n update buffer requirements");
8057 return OMX_ErrorHardware;
8058 }
8059 portDefn->nBufferSize = buf_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008060 portDefn->eDir = OMX_DirOutput;
Vinay Kaliafeef7032012-09-25 19:23:33 -07008061 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8062 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008063 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8064 portDefn->bEnabled = m_out_bEnabled;
8065 portDefn->bPopulated = m_out_bPopulated;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008066 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
8067 DEBUG_PRINT_ERROR("\n Error in getting color format");
8068 return OMX_ErrorHardware;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008069 }
8070 }
8071 else
8072 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008073 portDefn->eDir = OMX_DirMax;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008074 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8075 (int)portDefn->nPortIndex);
8076 eRet = OMX_ErrorBadPortIndex;
8077 }
8078 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8079 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8080 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8081 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008082 DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld"
8083 " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08008084 portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008085 portDefn->format.video.nStride,
8086 portDefn->format.video.nSliceHeight);
8087 return eRet;
8088
8089}
8090
8091OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8092{
8093 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8094 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8095 unsigned i= 0;
8096
8097 if(!m_out_mem_ptr) {
8098 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
8099 int nBufHdrSize = 0;
8100 int nPlatformEntrySize = 0;
8101 int nPlatformListSize = 0;
8102 int nPMEMInfoSize = 0;
8103 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8104 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8105 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
8106
8107 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
8108 drv_ctx.op_buf.actualcount);
8109 nBufHdrSize = drv_ctx.op_buf.actualcount *
8110 sizeof(OMX_BUFFERHEADERTYPE);
8111
8112 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8113 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8114 nPlatformListSize = drv_ctx.op_buf.actualcount *
8115 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8116 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8117 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
8118
8119 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
8120 sizeof(OMX_BUFFERHEADERTYPE),
8121 nPMEMInfoSize,
8122 nPlatformListSize);
8123 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
8124 m_out_bm_count);
8125 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8126 // Alloc mem for platform specific info
8127 char *pPtr=NULL;
8128 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8129 nPMEMInfoSize,1);
8130 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8131 calloc (sizeof(struct vdec_bufferpayload),
8132 drv_ctx.op_buf.actualcount);
8133 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8134 calloc (sizeof (struct vdec_output_frameinfo),
8135 drv_ctx.op_buf.actualcount);
8136#ifdef USE_ION
8137 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8138 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
8139#endif
8140
8141 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8142 && drv_ctx.ptr_respbuffer)
8143 {
8144 bufHdr = m_out_mem_ptr;
8145 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8146 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8147 (((char *) m_platform_list) + nPlatformListSize);
8148 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8149 (((char *) m_platform_entry) + nPlatformEntrySize);
8150 pPlatformList = m_platform_list;
8151 pPlatformEntry = m_platform_entry;
8152 pPMEMInfo = m_pmem_info;
8153
8154 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
8155
8156 // Settting the entire storage nicely
8157 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
8158 m_out_mem_ptr,pPlatformEntry);
8159 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
8160 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
8161 {
8162 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8163 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8164 // Set the values when we determine the right HxW param
8165 bufHdr->nAllocLen = 0;
8166 bufHdr->nFilledLen = 0;
8167 bufHdr->pAppPrivate = NULL;
8168 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8169 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8170 pPlatformEntry->entry = pPMEMInfo;
8171 // Initialize the Platform List
8172 pPlatformList->nEntries = 1;
8173 pPlatformList->entryList = pPlatformEntry;
8174 // Keep pBuffer NULL till vdec is opened
8175 bufHdr->pBuffer = NULL;
8176 pPMEMInfo->offset = 0;
8177 pPMEMInfo->pmem_fd = 0;
8178 bufHdr->pPlatformPrivate = pPlatformList;
8179 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
8180#ifdef USE_ION
8181 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
8182#endif
8183 /*Create a mapping between buffers*/
8184 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8185 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8186 &drv_ctx.ptr_outputbuffer[i];
8187 // Move the buffer and buffer header pointers
8188 bufHdr++;
8189 pPMEMInfo++;
8190 pPlatformEntry++;
8191 pPlatformList++;
8192 }
8193 }
8194 else
8195 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008196 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
Shalaj Jain273b3e02012-06-22 19:08:03 -07008197 m_out_mem_ptr, pPtr);
8198 if(m_out_mem_ptr)
8199 {
8200 free(m_out_mem_ptr);
8201 m_out_mem_ptr = NULL;
8202 }
8203 if(pPtr)
8204 {
8205 free(pPtr);
8206 pPtr = NULL;
8207 }
8208 if(drv_ctx.ptr_outputbuffer)
8209 {
8210 free(drv_ctx.ptr_outputbuffer);
8211 drv_ctx.ptr_outputbuffer = NULL;
8212 }
8213 if(drv_ctx.ptr_respbuffer)
8214 {
8215 free(drv_ctx.ptr_respbuffer);
8216 drv_ctx.ptr_respbuffer = NULL;
8217 }
8218#ifdef USE_ION
8219 if (drv_ctx.op_buf_ion_info) {
8220 DEBUG_PRINT_LOW("\n Free o/p ion context");
8221 free(drv_ctx.op_buf_ion_info);
8222 drv_ctx.op_buf_ion_info = NULL;
8223 }
8224#endif
8225 eRet = OMX_ErrorInsufficientResources;
8226 }
8227 } else {
8228 eRet = OMX_ErrorInsufficientResources;
8229 }
8230 return eRet;
8231}
8232
8233void omx_vdec::complete_pending_buffer_done_cbs()
8234{
8235 unsigned p1;
8236 unsigned p2;
8237 unsigned ident;
8238 omx_cmd_queue tmp_q, pending_bd_q;
8239 pthread_mutex_lock(&m_lock);
8240 // pop all pending GENERATE FDB from ftb queue
8241 while (m_ftb_q.m_size)
8242 {
8243 m_ftb_q.pop_entry(&p1,&p2,&ident);
8244 if(ident == OMX_COMPONENT_GENERATE_FBD)
8245 {
8246 pending_bd_q.insert_entry(p1,p2,ident);
8247 }
8248 else
8249 {
8250 tmp_q.insert_entry(p1,p2,ident);
8251 }
8252 }
8253 //return all non GENERATE FDB to ftb queue
8254 while(tmp_q.m_size)
8255 {
8256 tmp_q.pop_entry(&p1,&p2,&ident);
8257 m_ftb_q.insert_entry(p1,p2,ident);
8258 }
8259 // pop all pending GENERATE EDB from etb queue
8260 while (m_etb_q.m_size)
8261 {
8262 m_etb_q.pop_entry(&p1,&p2,&ident);
8263 if(ident == OMX_COMPONENT_GENERATE_EBD)
8264 {
8265 pending_bd_q.insert_entry(p1,p2,ident);
8266 }
8267 else
8268 {
8269 tmp_q.insert_entry(p1,p2,ident);
8270 }
8271 }
8272 //return all non GENERATE FDB to etb queue
8273 while(tmp_q.m_size)
8274 {
8275 tmp_q.pop_entry(&p1,&p2,&ident);
8276 m_etb_q.insert_entry(p1,p2,ident);
8277 }
8278 pthread_mutex_unlock(&m_lock);
8279 // process all pending buffer dones
8280 while(pending_bd_q.m_size)
8281 {
8282 pending_bd_q.pop_entry(&p1,&p2,&ident);
8283 switch(ident)
8284 {
8285 case OMX_COMPONENT_GENERATE_EBD:
8286 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
8287 {
8288 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
8289 omx_report_error ();
8290 }
8291 break;
8292
8293 case OMX_COMPONENT_GENERATE_FBD:
8294 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
8295 {
8296 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
8297 omx_report_error ();
8298 }
8299 break;
8300 }
8301 }
8302}
8303
8304void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8305{
8306 OMX_U32 new_frame_interval = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008307 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8308 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000))
8309 {
8310 new_frame_interval = (act_timestamp > prev_ts)?
8311 act_timestamp - prev_ts :
8312 prev_ts - act_timestamp;
8313 if (new_frame_interval < frm_int || frm_int == 0)
8314 {
8315 frm_int = new_frame_interval;
8316 if(frm_int)
8317 {
8318 drv_ctx.frame_rate.fps_numerator = 1e6;
8319 drv_ctx.frame_rate.fps_denominator = frm_int;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008320 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008321 frm_int, drv_ctx.frame_rate.fps_numerator /
8322 (float)drv_ctx.frame_rate.fps_denominator);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008323 }
8324 }
8325 }
8326 prev_ts = act_timestamp;
8327}
8328
8329void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8330{
8331 if (rst_prev_ts && VALID_TS(act_timestamp))
8332 {
8333 prev_ts = act_timestamp;
8334 rst_prev_ts = false;
8335 }
8336 else if (VALID_TS(prev_ts))
8337 {
8338 bool codec_cond = (drv_ctx.timestamp_adjust)?
8339 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8340 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8341 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8342 if(frm_int > 0 && codec_cond)
8343 {
8344 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8345 act_timestamp = prev_ts + frm_int;
8346 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8347 prev_ts = act_timestamp;
8348 }
8349 else
8350 set_frame_rate(act_timestamp);
8351 }
8352 else if (frm_int > 0) // In this case the frame rate was set along
8353 { // with the port definition, start ts with 0
8354 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8355 rst_prev_ts = true;
8356 }
8357}
8358
8359void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8360{
8361 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8362 OMX_U32 num_conceal_MB = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008363 OMX_U32 frame_rate = 0;
Praneeth Paladugu32284302013-02-14 22:53:06 -08008364 int consumed_len = 0;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008365 OMX_U32 num_MB_in_frame;
8366 OMX_U32 recovery_sei_flags = 1;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008367 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008368 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
Shalaj Jain286b0062013-02-21 20:35:48 -08008369 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
8370 p_buf_hdr->nOffset;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008371 if (!drv_ctx.extradata_info.uaddr) {
8372 return;
8373 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008374 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008375 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8376 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8377 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
Shalaj Jain273b3e02012-06-22 19:08:03 -07008378 p_extra = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008379 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008380 if (data) {
8381 while((consumed_len < drv_ctx.extradata_info.buffer_size)
Shalaj Jain286b0062013-02-21 20:35:48 -08008382 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008383 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008384 DEBUG_PRINT_LOW("Invalid extra data size");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008385 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008386 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008387 switch((unsigned long)data->eType) {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008388 case EXTRADATA_INTERLACE_VIDEO:
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008389 struct msm_vidc_interlace_payload *payload;
8390 payload = (struct msm_vidc_interlace_payload *)data->data;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008391 if (payload->format != INTERLACE_FRAME_PROGRESSIVE) {
8392 int enable = 1;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008393 OMX_U32 mbaff = 0;
8394 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8395 if ((payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8396 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8397 else
8398 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8399 if(m_enable_android_native_buffers)
8400 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008401 PP_PARAM_INTERLACED, (void*)&enable);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008402 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008403 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8404 append_interlace_extradata(p_extra, payload->format);
8405 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8406 }
8407 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008408 case EXTRADATA_FRAME_RATE:
8409 struct msm_vidc_framerate_payload *frame_rate_payload;
8410 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8411 frame_rate = frame_rate_payload->frame_rate;
8412 break;
8413 case EXTRADATA_TIMESTAMP:
8414 struct msm_vidc_ts_payload *time_stamp_payload;
8415 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008416 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
Shalaj Jain286b0062013-02-21 20:35:48 -08008417 p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008418 break;
8419 case EXTRADATA_NUM_CONCEALED_MB:
8420 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8421 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8422 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8423 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8424 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8425 break;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008426 case EXTRADATA_ASPECT_RATIO:
8427 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8428 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)data->data;
8429 ((struct vdec_output_frameinfo *)
8430 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8431 ((struct vdec_output_frameinfo *)
8432 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8433 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008434 case EXTRADATA_RECOVERY_POINT_SEI:
8435 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8436 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8437 recovery_sei_flags = recovery_sei_payload->flags;
8438 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8439 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008440 DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received\n");
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008441 }
8442 break;
8443 case EXTRADATA_PANSCAN_WINDOW:
8444 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8445 break;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008446 default:
8447 goto unrecognized_extradata;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008448 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008449 consumed_len += data->nSize;
8450 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008451 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008452 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08008453 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008454 append_frame_info_extradata(p_extra,
8455 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008456 panscan_payload,&((struct vdec_output_frameinfo *)
8457 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008458 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008459unrecognized_extradata:
8460 if(!secure_mode && client_extradata)
8461 append_terminator_extradata(p_extra);
8462 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008463}
8464
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008465OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
8466 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008467{
8468 OMX_ERRORTYPE ret = OMX_ErrorNone;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008469 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008470 if(m_state != OMX_StateLoaded)
8471 {
8472 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8473 return OMX_ErrorIncorrectStateOperation;
8474 }
Praneeth Paladugu32284302013-02-14 22:53:06 -08008475 DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008476 client_extradata, requested_extradata, enable, is_internal);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008477
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008478 if (!is_internal) {
8479 if (enable)
8480 client_extradata |= requested_extradata;
8481 else
8482 client_extradata = client_extradata & ~requested_extradata;
8483 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008484
8485 if (enable) {
8486 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8487 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8488 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8489 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8490 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8491 " Quality of interlaced clips might be impacted.\n");
8492 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008493 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8494 {
8495 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8496 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8497 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8498 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8499 }
8500 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8501 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8502 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8503 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8504 }
8505 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8506 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8507 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8508 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8509 }
8510 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8511 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8512 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8513 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8514 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008515 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8516 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8517 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8518 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8519 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008520 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA)
8521 {
8522 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8523 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8524 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8525 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8526 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008527 }
8528 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008529 return ret;
8530}
8531
8532OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8533{
8534 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8535 OMX_U8 *data_ptr = extra->data, data = 0;
8536 while (byte_count < extra->nDataSize)
8537 {
8538 data = *data_ptr;
8539 while (data)
8540 {
8541 num_MB += (data&0x01);
8542 data >>= 1;
8543 }
8544 data_ptr++;
8545 byte_count++;
8546 }
8547 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8548 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8549 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8550}
8551
8552void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8553{
8554 if (!m_debug_extradata)
8555 return;
8556
8557 DEBUG_PRINT_HIGH(
8558 "============== Extra Data ==============\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008559 " Size: %lu \n"
8560 " Version: %lu \n"
8561 " PortIndex: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008562 " Type: %x \n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008563 " DataSize: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008564 extra->nSize, extra->nVersion.nVersion,
8565 extra->nPortIndex, extra->eType, extra->nDataSize);
8566
Shalaj Jain286b0062013-02-21 20:35:48 -08008567 if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008568 {
8569 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8570 DEBUG_PRINT_HIGH(
8571 "------ Interlace Format ------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008572 " Size: %lu \n"
8573 " Version: %lu \n"
8574 " PortIndex: %lu \n"
8575 " Is Interlace Format: %d \n"
8576 " Interlace Formats: %lu \n"
Shalaj Jain273b3e02012-06-22 19:08:03 -07008577 "=========== End of Interlace ===========\n",
8578 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8579 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8580 }
Shalaj Jain286b0062013-02-21 20:35:48 -08008581 else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008582 {
8583 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8584
8585 DEBUG_PRINT_HIGH(
8586 "-------- Frame Format --------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008587 " Picture Type: %d \n"
8588 " Interlace Type: %d \n"
8589 " Pan Scan Total Frame Num: %lu \n"
8590 " Concealed Macro Blocks: %lu \n"
8591 " frame rate: %lu \n"
8592 " Aspect Ratio X: %lu \n"
8593 " Aspect Ratio Y: %lu \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008594 fminfo->ePicType,
8595 fminfo->interlaceType,
8596 fminfo->panScan.numWindows,
8597 fminfo->nConcealedMacroblocks,
8598 fminfo->nFrameRate,
8599 fminfo->aspectRatio.aspectRatioX,
8600 fminfo->aspectRatio.aspectRatioY);
8601
Praneeth Paladugu32284302013-02-14 22:53:06 -08008602 for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008603 {
8604 DEBUG_PRINT_HIGH(
8605 "------------------------------\n"
Praneeth Paladugu32284302013-02-14 22:53:06 -08008606 " Pan Scan Frame Num: %lu \n"
8607 " Rectangle x: %ld \n"
8608 " Rectangle y: %ld \n"
8609 " Rectangle dx: %ld \n"
8610 " Rectangle dy: %ld \n",
Shalaj Jain273b3e02012-06-22 19:08:03 -07008611 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8612 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8613 }
8614
8615 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8616 }
8617 else if (extra->eType == OMX_ExtraDataNone)
8618 {
8619 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8620 }
8621 else
8622 {
8623 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8624 }
8625}
8626
8627void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8628 OMX_U32 interlaced_format_type)
8629{
8630 OMX_STREAMINTERLACEFORMAT *interlace_format;
8631 OMX_U32 mbaff = 0;
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008632 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8633 return;
8634 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008635 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8636 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8637 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8638 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8639 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8640 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8641 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8642 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8643 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8644 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008645 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008646 {
8647 interlace_format->bInterlaceFormat = OMX_FALSE;
8648 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8649 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8650 }
8651 else
8652 {
8653 interlace_format->bInterlaceFormat = OMX_TRUE;
8654 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8655 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8656 }
8657 print_debug_extradata(extra);
8658}
8659
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008660void omx_vdec::fill_aspect_ratio_info(
8661 struct vdec_aspectratioinfo *aspect_ratio_info,
8662 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
8663{
8664 m_extradata = frame_info;
8665 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8666 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008667 DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008668 m_extradata->aspectRatio.aspectRatioY);
8669}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008670
8671void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008672 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008673 struct msm_vidc_panscan_window_payload *panscan_payload,
8674 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008675{
8676 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008677 struct msm_vidc_panscan_window *panscan_window;
8678 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8679 return;
8680 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008681 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8682 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8683 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8684 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8685 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8686 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8687 switch (picture_type)
8688 {
8689 case PICTURE_TYPE_I:
8690 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8691 break;
8692 case PICTURE_TYPE_P:
8693 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8694 break;
8695 case PICTURE_TYPE_B:
8696 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8697 break;
8698 default:
8699 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8700 }
8701 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8702 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8703 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8704 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8705 else
8706 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008707 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
Shalaj Jain273b3e02012-06-22 19:08:03 -07008708 frame_info->nConcealedMacroblocks = num_conceal_mb;
8709 frame_info->nFrameRate = frame_rate;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008710 frame_info->panScan.numWindows = 0;
8711 if(panscan_payload) {
8712 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8713 panscan_window = &panscan_payload->wnd[0];
Praneeth Paladugu32284302013-02-14 22:53:06 -08008714 for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++)
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008715 {
8716 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8717 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8718 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8719 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8720 panscan_window++;
8721 }
8722 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008723 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008724 print_debug_extradata(extra);
8725}
8726
8727void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8728{
8729 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8730 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8731 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8732 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8733 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8734 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8735 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8736 *portDefn = m_port_def;
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008737 DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
8738 "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008739 portDefn->format.video.nFrameWidth,
8740 portDefn->format.video.nStride,
8741 portDefn->format.video.nSliceHeight);
8742}
8743
8744void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8745{
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008746 if (!client_extradata) {
8747 return;
8748 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008749 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8750 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8751 extra->eType = OMX_ExtraDataNone;
8752 extra->nDataSize = 0;
8753 extra->data[0] = 0;
8754
8755 print_debug_extradata(extra);
8756}
8757
8758OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8759{
8760 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8761 if (index >= drv_ctx.ip_buf.actualcount)
8762 {
8763 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8764 return OMX_ErrorInsufficientResources;
8765 }
8766 if (m_desc_buffer_ptr == NULL)
8767 {
8768 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8769 calloc( (sizeof(desc_buffer_hdr)),
8770 drv_ctx.ip_buf.actualcount);
8771 if (m_desc_buffer_ptr == NULL)
8772 {
8773 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8774 return OMX_ErrorInsufficientResources;
8775 }
8776 }
8777
8778 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8779 if (m_desc_buffer_ptr[index].buf_addr == NULL)
8780 {
8781 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8782 return OMX_ErrorInsufficientResources;
8783 }
8784
8785 return eRet;
8786}
8787
8788void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8789{
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008790 DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008791 if (m_demux_entries < 8192)
8792 {
8793 m_demux_offsets[m_demux_entries++] = address_offset;
8794 }
8795 return;
8796}
8797
8798void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8799{
8800 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8801 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8802 OMX_U32 index = 0;
8803
8804 m_demux_entries = 0;
8805
8806 while (index < bytes_to_parse)
8807 {
8808 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8809 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8810 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8811 (buf[index+2] == 0x01)) )
8812 {
8813 //Found start code, insert address offset
8814 insert_demux_addr_offset(index);
8815 if (buf[index+2] == 0x01) // 3 byte start code
8816 index += 3;
8817 else //4 byte start code
8818 index += 4;
8819 }
8820 else
8821 index++;
8822 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008823 DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008824 return;
8825}
8826
8827OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8828{
8829 //fix this, handle 3 byte start code, vc1 terminator entry
8830 OMX_U8 *p_demux_data = NULL;
8831 OMX_U32 desc_data = 0;
8832 OMX_U32 start_addr = 0;
8833 OMX_U32 nal_size = 0;
8834 OMX_U32 suffix_byte = 0;
8835 OMX_U32 demux_index = 0;
8836 OMX_U32 buffer_index = 0;
8837
8838 if (m_desc_buffer_ptr == NULL)
8839 {
8840 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8841 return OMX_ErrorBadParameter;
8842 }
8843
8844 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8845 if (buffer_index > drv_ctx.ip_buf.actualcount)
8846 {
Praneeth Paladugu32284302013-02-14 22:53:06 -08008847 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008848 return OMX_ErrorBadParameter;
8849 }
8850
8851 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8852
8853 if ( ((OMX_U8*)p_demux_data == NULL) ||
8854 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
8855 {
8856 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8857 return OMX_ErrorBadParameter;
8858 }
8859 else
8860 {
8861 for (; demux_index < m_demux_entries; demux_index++)
8862 {
8863 desc_data = 0;
8864 start_addr = m_demux_offsets[demux_index];
8865 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
8866 {
8867 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8868 }
8869 else
8870 {
8871 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8872 }
8873 if (demux_index < (m_demux_entries - 1))
8874 {
8875 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8876 }
8877 else
8878 {
8879 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8880 }
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008881 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
8882 (void *)start_addr,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008883 suffix_byte,
8884 nal_size,
8885 demux_index);
8886 desc_data = (start_addr >> 3) << 1;
8887 desc_data |= (start_addr & 7) << 21;
8888 desc_data |= suffix_byte << 24;
8889
8890 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8891 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8892 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8893 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8894
8895 p_demux_data += 16;
8896 }
8897 if (codec_type_parse == CODEC_TYPE_VC1)
8898 {
8899 DEBUG_PRINT_LOW("VC1 terminator entry");
8900 desc_data = 0;
8901 desc_data = 0x82 << 24;
8902 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8903 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8904 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8905 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8906 p_demux_data += 16;
8907 m_demux_entries++;
8908 }
8909 //Add zero word to indicate end of descriptors
8910 memset(p_demux_data, 0, sizeof(OMX_U32));
8911
8912 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
Deva Ramasubramanianfb760d52013-03-13 12:28:24 -07008913 DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008914 }
8915 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8916 m_demux_entries = 0;
8917 DEBUG_PRINT_LOW("Demux table complete!");
8918 return OMX_ErrorNone;
8919}
8920
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008921OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008922{
8923 OMX_ERRORTYPE err = OMX_ErrorNone;
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008924 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
Shalaj Jain273b3e02012-06-22 19:08:03 -07008925 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07008926 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8927 if(err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008928 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008929 delete iDivXDrmDecrypt;
8930 iDivXDrmDecrypt = NULL;
8931 }
8932 }
8933 else {
8934 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008935 err = OMX_ErrorUndefined;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008936 }
8937 return err;
8938}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008939
Vinay Kaliada4f4422013-01-09 10:45:03 -08008940omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8941{
8942 enabled = false;
8943 omx = NULL;
8944 init_members();
8945 ColorFormat = OMX_COLOR_FormatMax;
8946}
8947
8948void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8949{
8950 omx = reinterpret_cast<omx_vdec*>(client);
8951}
8952
8953void omx_vdec::allocate_color_convert_buf::init_members() {
8954 allocated_count = 0;
8955 buffer_size_req = 0;
8956 buffer_alignment_req = 0;
8957 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8958 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8959 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8960 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
8961#ifdef USE_ION
8962 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
8963#endif
8964 for (int i = 0; i < MAX_COUNT;i++)
8965 pmem_fd[i] = -1;
8966}
8967
8968omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() {
8969 c2d.destroy();
8970}
8971
8972bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8973{
8974 bool status = true;
8975 unsigned int src_size = 0, destination_size = 0;
8976 OMX_COLOR_FORMATTYPE drv_color_format;
8977 if (!omx){
8978 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8979 return false;
8980 }
8981 if (!enabled){
8982 DEBUG_PRINT_ERROR("\n No color conversion required");
8983 return status;
8984 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008985 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08008986 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8987 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8988 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08008989 status = false;
8990 goto fail_update_buf_req;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008991 }
8992 c2d.close();
8993 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8994 omx->drv_ctx.video_resolution.frame_width,
8995 NV12_128m,YCbCr420P);
8996 if (status) {
8997 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8998 if (status)
8999 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9000 }
9001 if (status) {
9002 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9003 !destination_size) {
9004 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
9005 "driver size %d destination size %d",
9006 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9007 status = false;
9008 c2d.close();
9009 buffer_size_req = 0;
9010 } else {
9011 buffer_size_req = destination_size;
9012 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9013 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9014 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9015 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9016 }
9017 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009018fail_update_buf_req:
9019 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009020 return status;
9021}
9022
9023bool omx_vdec::allocate_color_convert_buf::set_color_format(
9024 OMX_COLOR_FORMATTYPE dest_color_format)
9025{
9026 bool status = true;
9027 OMX_COLOR_FORMATTYPE drv_color_format;
9028 if (!omx){
9029 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9030 return false;
9031 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009032 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009033 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9034 drv_color_format = (OMX_COLOR_FORMATTYPE)
9035 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9036 else {
9037 DEBUG_PRINT_ERROR("\n Incorrect color format");
9038 status = false;
9039 }
9040 if (status && (drv_color_format != dest_color_format)) {
9041 DEBUG_PRINT_LOW("Enabling C2D\n");
9042 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
9043 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
9044 status = false;
9045 } else {
9046 ColorFormat = OMX_COLOR_FormatYUV420Planar;
9047 if (enabled)
9048 c2d.destroy();
9049 enabled = false;
9050 if (!c2d.init()) {
9051 DEBUG_PRINT_ERROR("\n open failed for c2d");
9052 status = false;
9053 } else
9054 enabled = true;
9055 }
9056 } else {
9057 if (enabled)
9058 c2d.destroy();
9059 enabled = false;
9060 }
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009061 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009062 return status;
9063}
9064
9065OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9066{
9067 if (!omx){
9068 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9069 return NULL;
9070 }
9071 if (!enabled)
9072 return omx->m_out_mem_ptr;
9073 return m_out_mem_ptr_client;
9074}
9075
9076OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9077 (OMX_BUFFERHEADERTYPE *bufadd)
9078{
9079 if (!omx){
9080 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9081 return NULL;
9082 }
9083 if (!enabled)
9084 return bufadd;
9085
9086 unsigned index = 0;
9087 index = bufadd - omx->m_out_mem_ptr;
9088 if (index < omx->drv_ctx.op_buf.actualcount) {
9089 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9090 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9091 bool status;
Praneeth Paladugu1a5ea502013-02-19 21:13:05 -08009092 if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009093 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009094 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9095 bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009096 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009097 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9098 if (!status){
9099 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009100 m_out_mem_ptr_client[index].nFilledLen = 0;
9101 return &m_out_mem_ptr_client[index];
Vinay Kaliada4f4422013-01-09 10:45:03 -08009102 }
9103 } else
9104 m_out_mem_ptr_client[index].nFilledLen = 0;
9105 return &m_out_mem_ptr_client[index];
9106 }
9107 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
9108 return NULL;
9109}
9110
9111OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9112 (OMX_BUFFERHEADERTYPE *bufadd)
9113{
9114 if (!omx){
9115 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9116 return NULL;
9117 }
9118 if (!enabled)
9119 return bufadd;
9120 unsigned index = 0;
9121 index = bufadd - m_out_mem_ptr_client;
9122 if (index < omx->drv_ctx.op_buf.actualcount) {
9123 return &omx->m_out_mem_ptr[index];
9124 }
9125 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
9126 return NULL;
9127}
9128bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9129 (unsigned int &buffer_size)
9130{
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009131 bool status = true;
9132 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009133 if (!enabled)
9134 buffer_size = omx->drv_ctx.op_buf.buffer_size;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009135 else {
Vinay Kaliada4f4422013-01-09 10:45:03 -08009136 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
9137 DEBUG_PRINT_ERROR("\n Get buffer size failed");
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009138 status = false;
9139 goto fail_get_buffer_size;
9140 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08009141 }
9142 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9143 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9144 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9145 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009146fail_get_buffer_size:
9147 pthread_mutex_unlock(&omx->c_lock);
9148 return status;
Vinay Kaliada4f4422013-01-09 10:45:03 -08009149}
9150OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
9151 OMX_BUFFERHEADERTYPE *bufhdr) {
9152 unsigned int index = 0;
9153
9154 if (!enabled)
9155 return omx->free_output_buffer(bufhdr);
9156 if (enabled && omx->is_component_secure())
9157 return OMX_ErrorNone;
9158 if (!allocated_count || !bufhdr) {
9159 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
9160 return OMX_ErrorBadParameter;
9161 }
9162 index = bufhdr - m_out_mem_ptr_client;
9163 if (index >= omx->drv_ctx.op_buf.actualcount){
9164 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
9165 return OMX_ErrorBadParameter;
9166 }
9167 if (pmem_fd[index] > 0) {
9168 munmap(pmem_baseaddress[index], buffer_size_req);
9169 close(pmem_fd[index]);
9170 }
9171 pmem_fd[index] = -1;
9172#ifdef USE_ION
9173 omx->free_ion_memory(&op_buf_ion_info[index]);
9174#endif
9175 m_heap_ptr[index].video_heap_ptr = NULL;
9176 if (allocated_count > 0)
9177 allocated_count--;
9178 else
9179 allocated_count = 0;
9180 if (!allocated_count) {
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009181 pthread_mutex_lock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009182 c2d.close();
9183 init_members();
Praneeth Paladuguf6995272013-02-04 14:03:56 -08009184 pthread_mutex_unlock(&omx->c_lock);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009185 }
9186 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
9187}
9188
9189OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
9190 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
9191{
9192 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9193 if (!enabled){
9194 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9195 return eRet;
9196 }
9197 if (enabled && omx->is_component_secure()) {
9198 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
9199 omx->is_component_secure());
9200 return OMX_ErrorUnsupportedSetting;
9201 }
9202 if (!bufferHdr || bytes > buffer_size_req) {
9203 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
Praneeth Paladugu32284302013-02-14 22:53:06 -08009204 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
Vinay Kaliada4f4422013-01-09 10:45:03 -08009205 buffer_size_req,bytes);
9206 return OMX_ErrorBadParameter;
9207 }
9208 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
9209 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
9210 return OMX_ErrorInsufficientResources;
9211 }
9212 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9213 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9214 port,appData,omx->drv_ctx.op_buf.buffer_size);
9215 if (eRet != OMX_ErrorNone || !temp_bufferHdr){
9216 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
9217 return eRet;
9218 }
9219 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
9220 omx->drv_ctx.op_buf.actualcount) {
9221 DEBUG_PRINT_ERROR("\n Invalid header index %d",
9222 (temp_bufferHdr - omx->m_out_mem_ptr));
9223 return OMX_ErrorUndefined;
9224 }
9225 unsigned int i = allocated_count;
9226#ifdef USE_ION
9227 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9228 buffer_size_req,buffer_alignment_req,
9229 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
Praneeth Paladugu827fd8f2013-02-26 19:02:22 -08009230 0);
Vinay Kaliada4f4422013-01-09 10:45:03 -08009231 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9232 if (op_buf_ion_info[i].ion_device_fd < 0) {
9233 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
9234 return OMX_ErrorInsufficientResources;
9235 }
9236 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9237 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
9238
9239 if (pmem_baseaddress[i] == MAP_FAILED) {
9240 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
9241 close(pmem_fd[i]);
9242 omx->free_ion_memory(&op_buf_ion_info[i]);
9243 return OMX_ErrorInsufficientResources;
9244 }
9245 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9246 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9247 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
9248#endif
9249 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9250 m_pmem_info_client[i].offset = 0;
9251 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9252 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9253 m_platform_list_client[i].nEntries = 1;
9254 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9255 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9256 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9257 m_out_mem_ptr_client[i].nFilledLen = 0;
9258 m_out_mem_ptr_client[i].nFlags = 0;
9259 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9260 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9261 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9262 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9263 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9264 m_out_mem_ptr_client[i].pAppPrivate = appData;
9265 *bufferHdr = &m_out_mem_ptr_client[i];
9266 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
9267 allocated_count++;
9268 return eRet;
9269}
9270
9271bool omx_vdec::is_component_secure()
9272{
9273 return secure_mode;
9274}
9275
9276bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9277{
9278 bool status = true;
9279 if (!enabled) {
9280 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9281 dest_color_format = (OMX_COLOR_FORMATTYPE)
9282 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9283 else
9284 status = false;
9285 } else {
9286 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9287 status = false;
9288 } else
9289 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9290 }
9291 return status;
9292}