blob: 712d93f1fea7a9e25aac5561f5a898464acfa651 [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 struct vdec_ioctl_msg ioctl_msg;
139 OMX_BUFFERHEADERTYPE *buffer;
140 struct v4l2_plane plane[VIDEO_MAX_PLANES];
141 struct pollfd pfd;
142 struct v4l2_buffer v4l2_buf ={0};
143 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========================================================================== */
501omx_vdec::omx_vdec(): m_state(OMX_StateInvalid),
502 m_app_data(NULL),
503 m_inp_mem_ptr(NULL),
504 m_out_mem_ptr(NULL),
505 m_phdr_pmem_ptr(NULL),
506 pending_input_buffers(0),
507 pending_output_buffers(0),
508 m_out_bm_count(0),
509 m_inp_bm_count(0),
510 m_inp_bPopulated(OMX_FALSE),
511 m_out_bPopulated(OMX_FALSE),
512 m_flags(0),
513 m_inp_bEnabled(OMX_TRUE),
514 m_out_bEnabled(OMX_TRUE),
515 m_platform_list(NULL),
516 m_platform_entry(NULL),
517 m_pmem_info(NULL),
518 output_flush_progress (false),
519 input_flush_progress (false),
520 input_use_buffer (false),
521 output_use_buffer (false),
522 arbitrary_bytes (true),
523 psource_frame (NULL),
524 pdest_frame (NULL),
525 m_inp_heap_ptr (NULL),
526 m_heap_inp_bm_count (0),
527 codec_type_parse ((codec_type)0),
528 first_frame_meta (true),
529 frame_count (0),
530 nal_length(0),
531 nal_count (0),
532 look_ahead_nal (false),
533 first_frame(0),
534 first_buffer(NULL),
535 first_frame_size (0),
536 m_error_propogated(false),
537 m_device_file_ptr(NULL),
538 m_vc1_profile((vc1_profile_type)0),
539 prev_ts(LLONG_MAX),
540 rst_prev_ts(true),
541 frm_int(0),
542 m_in_alloc_cnt(0),
543 m_display_id(NULL),
544 ouput_egl_buffers(false),
545 h264_parser(NULL),
546 client_extradata(0),
547 h264_last_au_ts(LLONG_MAX),
548 h264_last_au_flags(0),
549 m_inp_err_count(0),
550#ifdef _ANDROID_
551 m_heap_ptr(NULL),
552 m_enable_android_native_buffers(OMX_FALSE),
553 m_use_android_native_buffers(OMX_FALSE),
554#endif
555 in_reconfig(false),
556 m_use_output_pmem(OMX_FALSE),
557 m_out_mem_region_smi(OMX_FALSE),
558 m_out_pvt_entry_pmem(OMX_FALSE),
559 secure_mode(false)
560#ifdef _ANDROID_
561 ,iDivXDrmDecrypt(NULL)
562#endif
563 ,m_desc_buffer_ptr(NULL)
564 ,streaming({false, false})
565{
566 /* Assumption is that , to begin with , we have all the frames with decoder */
567 DEBUG_PRINT_HIGH("In OMX vdec Constructor");
568#ifdef _ANDROID_
569 char property_value[PROPERTY_VALUE_MAX] = {0};
570 property_get("vidc.dec.debug.perf", property_value, "0");
571 perf_flag = atoi(property_value);
572 if (perf_flag)
573 {
574 DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
575 dec_time.start();
576 proc_frms = latency = 0;
577 }
578 property_value[0] = NULL;
579 property_get("vidc.dec.debug.ts", property_value, "0");
580 m_debug_timestamp = atoi(property_value);
581 DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
582 if (m_debug_timestamp)
583 {
584 time_stamp_dts.set_timestamp_reorder_mode(true);
585 }
586
587 property_value[0] = NULL;
588 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);
608 sem_init(&m_cmd_lock,0,0);
609#ifdef _ANDROID_
610 char extradata_value[PROPERTY_VALUE_MAX] = {0};
611 property_get("vidc.dec.debug.extradata", extradata_value, "0");
612 m_debug_extradata = atoi(extradata_value);
613 DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
614#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -0800615 m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
616 client_buffers.set_vdec_client(this);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700617}
618
Vinay Kalia85793762012-06-14 19:12:34 -0700619static const int event_type[] = {
620 V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
621 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
622 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
Praneeth Paladugu268314a2012-08-23 11:33:28 -0700623 V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
624 V4L2_EVENT_MSM_VIDC_SYS_ERROR
Vinay Kalia85793762012-06-14 19:12:34 -0700625};
626
627static OMX_ERRORTYPE subscribe_to_events(int fd)
628{
629 OMX_ERRORTYPE eRet = OMX_ErrorNone;
630 struct v4l2_event_subscription sub;
631 int array_sz = sizeof(event_type)/sizeof(int);
632 int i,rc;
633 if (fd < 0) {
634 printf("Invalid input: %d\n", fd);
635 return OMX_ErrorBadParameter;
636 }
637
638 for (i = 0; i < array_sz; ++i) {
639 memset(&sub, 0, sizeof(sub));
640 sub.type = event_type[i];
641 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
642 if (rc) {
643 printf("Failed to subscribe event: 0x%x\n", sub.type);
644 break;
645 }
646 }
647 if (i < array_sz) {
648 for (--i; i >=0 ; i--) {
649 memset(&sub, 0, sizeof(sub));
650 sub.type = event_type[i];
651 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
652 if (rc)
653 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
654 }
655 eRet = OMX_ErrorNotImplemented;
656 }
657 return eRet;
658}
659
660
661static OMX_ERRORTYPE unsubscribe_to_events(int fd)
662{
663 OMX_ERRORTYPE eRet = OMX_ErrorNone;
664 struct v4l2_event_subscription sub;
665 int array_sz = sizeof(event_type)/sizeof(int);
666 int i,rc;
667 if (fd < 0) {
668 printf("Invalid input: %d\n", fd);
669 return OMX_ErrorBadParameter;
670 }
671
672 for (i = 0; i < array_sz; ++i) {
673 memset(&sub, 0, sizeof(sub));
674 sub.type = event_type[i];
675 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
676 if (rc) {
677 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
678 break;
679 }
680 }
681 return eRet;
682}
Shalaj Jain273b3e02012-06-22 19:08:03 -0700683
684/* ======================================================================
685FUNCTION
686 omx_vdec::~omx_vdec
687
688DESCRIPTION
689 Destructor
690
691PARAMETERS
692 None
693
694RETURN VALUE
695 None.
696========================================================================== */
697omx_vdec::~omx_vdec()
698{
699 m_pmem_info = NULL;
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700700 struct v4l2_decoder_cmd dec;
Shalaj Jain273b3e02012-06-22 19:08:03 -0700701 DEBUG_PRINT_HIGH("In OMX vdec Destructor");
702 if(m_pipe_in) close(m_pipe_in);
703 if(m_pipe_out) close(m_pipe_out);
704 m_pipe_in = -1;
705 m_pipe_out = -1;
706 DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
707 pthread_join(msg_thread_id,NULL);
708 DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
Praneeth Paladugu74a784e2012-08-01 16:29:44 -0700709 dec.cmd = V4L2_DEC_CMD_STOP;
710 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
711 {
712 DEBUG_PRINT_ERROR("\n STOP Command failed\n");
713 }
Shalaj Jain273b3e02012-06-22 19:08:03 -0700714 pthread_join(async_thread_id,NULL);
Vinay Kalia85793762012-06-14 19:12:34 -0700715 unsubscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700716 close(drv_ctx.video_driver_fd);
717 pthread_mutex_destroy(&m_lock);
718 sem_destroy(&m_cmd_lock);
719 if (perf_flag)
720 {
721 DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
722 dec_time.end();
723 }
724 DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
725}
726
Vinay Kaliafeef7032012-09-25 19:23:33 -0700727int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) {
728 struct v4l2_requestbuffers bufreq;
729 int rc = 0;
730 if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
731 bufreq.memory = V4L2_MEMORY_USERPTR;
732 bufreq.count = 0;
733 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
734 rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
735 }
736 return rc;
737}
738
Shalaj Jain273b3e02012-06-22 19:08:03 -0700739/* ======================================================================
740FUNCTION
741 omx_vdec::OMXCntrlProcessMsgCb
742
743DESCRIPTION
744 IL Client callbacks are generated through this routine. The decoder
745 provides the thread context for this routine.
746
747PARAMETERS
748 ctxt -- Context information related to the self.
749 id -- Event identifier. This could be any of the following:
750 1. Command completion event
751 2. Buffer done callback event
752 3. Frame done callback event
753
754RETURN VALUE
755 None.
756
757========================================================================== */
758void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
759{
760 unsigned p1; // Parameter - 1
761 unsigned p2; // Parameter - 2
762 unsigned ident;
763 unsigned qsize=0; // qsize
764 omx_vdec *pThis = (omx_vdec *) ctxt;
765
766 if(!pThis)
767 {
768 DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
769 __func__);
770 return;
771 }
772
773 // Protect the shared queue data structure
774 do
775 {
776 /*Read the message id's from the queue*/
777 pthread_mutex_lock(&pThis->m_lock);
778 qsize = pThis->m_cmd_q.m_size;
779 if(qsize)
780 {
781 pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
782 }
783
784 if (qsize == 0 && pThis->m_state != OMX_StatePause)
785 {
786 qsize = pThis->m_ftb_q.m_size;
787 if (qsize)
788 {
789 pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
790 }
791 }
792
793 if (qsize == 0 && pThis->m_state != OMX_StatePause)
794 {
795 qsize = pThis->m_etb_q.m_size;
796 if (qsize)
797 {
798 pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
799 }
800 }
801 pthread_mutex_unlock(&pThis->m_lock);
802
803 /*process message if we have one*/
804 if(qsize > 0)
805 {
806 id = ident;
807 switch (id)
808 {
809 case OMX_COMPONENT_GENERATE_EVENT:
810 if (pThis->m_cb.EventHandler)
811 {
812 switch (p1)
813 {
814 case OMX_CommandStateSet:
815 pThis->m_state = (OMX_STATETYPE) p2;
816 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
817 pThis->m_state);
818 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
819 OMX_EventCmdComplete, p1, p2, NULL);
820 break;
821
822 case OMX_EventError:
823 if(p2 == OMX_StateInvalid)
824 {
825 DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
826 pThis->m_state = (OMX_STATETYPE) p2;
827 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
828 OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
829 }
830 else if (p2 == OMX_ErrorHardware)
831 {
832 pThis->omx_report_error();
833 }
834 else
835 {
836 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
837 OMX_EventError, p2, NULL, NULL );
838 }
839 break;
840
841 case OMX_CommandPortDisable:
842 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
843 if (BITMASK_PRESENT(&pThis->m_flags,
844 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
845 {
846 BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
847 break;
848 }
849 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig)
850 {
Shalaj Jain273b3e02012-06-22 19:08:03 -0700851 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -0700852 pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
Vinay Kaliafeef7032012-09-25 19:23:33 -0700853 if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
854 DEBUG_PRINT_HIGH("Failed to release output buffers\n");
855 OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -0700856 pThis->in_reconfig = false;
857 if(eRet != OMX_ErrorNone)
858 {
859 DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
860 pThis->omx_report_error();
861 break;
862 }
863 }
864 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
865 OMX_EventCmdComplete, p1, p2, NULL );
866 break;
867 case OMX_CommandPortEnable:
868 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
869 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
870 OMX_EventCmdComplete, p1, p2, NULL );
871 break;
872
873 default:
874 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
875 OMX_EventCmdComplete, p1, p2, NULL );
876 break;
877
878 }
879 }
880 else
881 {
882 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
883 }
884 break;
885 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
886 if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
887 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
888 {
889 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
890 pThis->omx_report_error ();
891 }
892 break;
893 case OMX_COMPONENT_GENERATE_ETB:
894 if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
895 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
896 {
897 DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
898 pThis->omx_report_error ();
899 }
900 break;
901
902 case OMX_COMPONENT_GENERATE_FTB:
903 if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
904 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
905 {
906 DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
907 pThis->omx_report_error ();
908 }
909 break;
910
911 case OMX_COMPONENT_GENERATE_COMMAND:
912 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
913 (OMX_U32)p2,(OMX_PTR)NULL);
914 break;
915
916 case OMX_COMPONENT_GENERATE_EBD:
917
918 if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR)
919 {
920 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
921 pThis->omx_report_error ();
922 }
923 else
924 {
925 if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1)
926 {
927 pThis->m_inp_err_count++;
928 pThis->time_stamp_dts.remove_time_stamp(
929 ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
930 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
931 ?true:false);
932 }
933 else
934 {
935 pThis->m_inp_err_count = 0;
936 }
937 if ( pThis->empty_buffer_done(&pThis->m_cmp,
938 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
939 {
940 DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
941 pThis->omx_report_error ();
942 }
943 if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
944 {
945 DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
946 pThis->omx_report_error ();
947 }
948 }
949 break;
950 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED:
951 {
952 int64_t *timestamp = (int64_t *)p1;
953 if (p1)
954 {
955 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
956 (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
957 ?true:false);
958 free(timestamp);
959 }
960 }
961 break;
962 case OMX_COMPONENT_GENERATE_FBD:
963 if (p2 != VDEC_S_SUCCESS)
964 {
965 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
966 pThis->omx_report_error ();
967 }
968 else if ( pThis->fill_buffer_done(&pThis->m_cmp,
969 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
970 {
971 DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
972 pThis->omx_report_error ();
973 }
974 break;
975
976 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
977 DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
978 if (!pThis->input_flush_progress)
979 {
980 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
981 }
982 else
983 {
984 pThis->execute_input_flush();
985 if (pThis->m_cb.EventHandler)
986 {
987 if (p2 != VDEC_S_SUCCESS)
988 {
989 DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
990 pThis->omx_report_error ();
991 }
992 else
993 {
994 /*Check if we need generate event for Flush done*/
995 if(BITMASK_PRESENT(&pThis->m_flags,
996 OMX_COMPONENT_INPUT_FLUSH_PENDING))
997 {
998 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
999 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
1000 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1001 OMX_EventCmdComplete,OMX_CommandFlush,
1002 OMX_CORE_INPUT_PORT_INDEX,NULL );
1003 }
1004 if (BITMASK_PRESENT(&pThis->m_flags,
1005 OMX_COMPONENT_IDLE_PENDING))
1006 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001007 if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001008 DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
1009 pThis->omx_report_error ();
1010 } else {
1011 pThis->streaming[OUTPUT_PORT] = false;
1012 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001013 if (!pThis->output_flush_progress)
1014 {
Vinay Kalia22046272012-09-28 20:16:05 -07001015 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
1016 pThis->post_event (NULL, VDEC_S_SUCCESS,\
1017 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001018 }
1019 }
1020 }
1021 }
1022 else
1023 {
1024 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1025 }
1026 }
1027 break;
1028
1029 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
1030 DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
1031 if (!pThis->output_flush_progress)
1032 {
1033 DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
1034 }
1035 else
1036 {
1037 pThis->execute_output_flush();
1038 if (pThis->m_cb.EventHandler)
1039 {
1040 if (p2 != VDEC_S_SUCCESS)
1041 {
1042 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
1043 pThis->omx_report_error ();
1044 }
1045 else
1046 {
1047 /*Check if we need generate event for Flush done*/
1048 if(BITMASK_PRESENT(&pThis->m_flags,
1049 OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
1050 {
1051 DEBUG_PRINT_LOW("\n Notify Output Flush done");
1052 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1053 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1054 OMX_EventCmdComplete,OMX_CommandFlush,
1055 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
1056 }
1057 if(BITMASK_PRESENT(&pThis->m_flags,
1058 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
1059 {
1060 DEBUG_PRINT_LOW("\n Internal flush complete");
1061 BITMASK_CLEAR (&pThis->m_flags,
1062 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
1063 if (BITMASK_PRESENT(&pThis->m_flags,
1064 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED))
1065 {
1066 pThis->post_event(OMX_CommandPortDisable,
1067 OMX_CORE_OUTPUT_PORT_INDEX,
1068 OMX_COMPONENT_GENERATE_EVENT);
1069 BITMASK_CLEAR (&pThis->m_flags,
1070 OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
1071
1072 }
1073 }
1074
1075 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
1076 {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07001077 if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
Vinay Kalia22046272012-09-28 20:16:05 -07001078 DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
1079 pThis->omx_report_error ();
1080 break;
1081 }
1082 pThis->streaming[CAPTURE_PORT] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001083 if (!pThis->input_flush_progress)
1084 {
Vinay Kalia22046272012-09-28 20:16:05 -07001085 DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
1086 pThis->post_event (NULL, VDEC_S_SUCCESS,\
1087 OMX_COMPONENT_GENERATE_STOP_DONE);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001088 }
1089 }
1090 }
1091 }
1092 else
1093 {
1094 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1095 }
1096 }
1097 break;
1098
1099 case OMX_COMPONENT_GENERATE_START_DONE:
1100 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
1101
1102 if (pThis->m_cb.EventHandler)
1103 {
1104 if (p2 != VDEC_S_SUCCESS)
1105 {
1106 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
1107 pThis->omx_report_error ();
1108 }
1109 else
1110 {
1111 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
1112 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1113 {
1114 DEBUG_PRINT_LOW("\n Move to executing");
1115 // Send the callback now
1116 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1117 pThis->m_state = OMX_StateExecuting;
1118 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1119 OMX_EventCmdComplete,OMX_CommandStateSet,
1120 OMX_StateExecuting, NULL);
1121 }
1122 else if (BITMASK_PRESENT(&pThis->m_flags,
1123 OMX_COMPONENT_PAUSE_PENDING))
1124 {
1125 if (/*ioctl (pThis->drv_ctx.video_driver_fd,
1126 VDEC_IOCTL_CMD_PAUSE,NULL ) < */0)
1127 {
1128 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
1129 pThis->omx_report_error ();
1130 }
1131 }
1132 }
1133 }
1134 else
1135 {
1136 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
1137 }
1138 break;
1139
1140 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
1141 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
1142 if (pThis->m_cb.EventHandler)
1143 {
1144 if (p2 != VDEC_S_SUCCESS)
1145 {
1146 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
1147 pThis->omx_report_error ();
1148 }
1149 else
1150 {
1151 pThis->complete_pending_buffer_done_cbs();
1152 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
1153 {
1154 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
1155 //Send the callback now
1156 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
1157 pThis->m_state = OMX_StatePause;
1158 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1159 OMX_EventCmdComplete,OMX_CommandStateSet,
1160 OMX_StatePause, NULL);
1161 }
1162 }
1163 }
1164 else
1165 {
1166 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1167 }
1168
1169 break;
1170
1171 case OMX_COMPONENT_GENERATE_RESUME_DONE:
1172 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
1173 if (pThis->m_cb.EventHandler)
1174 {
1175 if (p2 != VDEC_S_SUCCESS)
1176 {
1177 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
1178 pThis->omx_report_error ();
1179 }
1180 else
1181 {
1182 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
1183 {
1184 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
1185 // Send the callback now
1186 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1187 pThis->m_state = OMX_StateExecuting;
1188 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1189 OMX_EventCmdComplete,OMX_CommandStateSet,
1190 OMX_StateExecuting,NULL);
1191 }
1192 }
1193 }
1194 else
1195 {
1196 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1197 }
1198
1199 break;
1200
1201 case OMX_COMPONENT_GENERATE_STOP_DONE:
1202 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1203 if (pThis->m_cb.EventHandler)
1204 {
1205 if (p2 != VDEC_S_SUCCESS)
1206 {
1207 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1208 pThis->omx_report_error ();
1209 }
1210 else
1211 {
1212 pThis->complete_pending_buffer_done_cbs();
1213 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
1214 {
1215 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
1216 // Send the callback now
1217 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1218 pThis->m_state = OMX_StateIdle;
1219 DEBUG_PRINT_LOW("\n Move to Idle State");
1220 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1221 OMX_EventCmdComplete,OMX_CommandStateSet,
1222 OMX_StateIdle,NULL);
1223 }
1224 }
1225 }
1226 else
1227 {
1228 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1229 }
1230
1231 break;
1232
1233 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1234 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001235
Vinay Kalia592e4b42012-12-19 15:55:47 -08001236 if (p2 == OMX_IndexParamPortDefinition) {
1237 pThis->in_reconfig = true;
1238 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001239 if (pThis->m_cb.EventHandler) {
1240 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
Vinay Kalia592e4b42012-12-19 15:55:47 -08001241 OMX_EventPortSettingsChanged, p1, p2, NULL );
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001242 } else {
1243 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1244 }
1245
1246 if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
Shalaj Jain273b3e02012-06-22 19:08:03 -07001247 {
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07001248 OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
1249 OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
1250 if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
1251 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
1252 else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
1253 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
1254 else //unsupported interlace format; raise a error
1255 event = OMX_EventError;
1256 if (pThis->m_cb.EventHandler) {
1257 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1258 event, format, 0, NULL );
1259 } else {
1260 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001261 }
1262 }
1263 break;
1264
1265 case OMX_COMPONENT_GENERATE_EOS_DONE:
1266 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1267 if (pThis->m_cb.EventHandler) {
1268 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1269 OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1270 } else {
1271 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1272 }
1273 pThis->prev_ts = LLONG_MAX;
1274 pThis->rst_prev_ts = true;
1275 break;
1276
1277 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1278 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1279 pThis->omx_report_error ();
1280 break;
1281 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG:
1282 {
1283 DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
1284 if (pThis->m_cb.EventHandler) {
1285 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1286 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1287 } else {
1288 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1289 }
1290 }
1291 default:
1292 break;
1293 }
1294 }
1295 pthread_mutex_lock(&pThis->m_lock);
1296 qsize = pThis->m_cmd_q.m_size;
1297 if (pThis->m_state != OMX_StatePause)
1298 qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1299 pthread_mutex_unlock(&pThis->m_lock);
1300 }
1301 while(qsize>0);
1302
1303}
1304
Vinay Kalia592e4b42012-12-19 15:55:47 -08001305void omx_vdec::update_resolution(int width, int height)
1306{
1307 drv_ctx.video_resolution.frame_height = height;
1308 drv_ctx.video_resolution.frame_width = width;
1309 drv_ctx.video_resolution.scan_lines = height;
1310 drv_ctx.video_resolution.stride = width;
1311 rectangle.nLeft = 0;
1312 rectangle.nTop = 0;
1313 rectangle.nWidth = drv_ctx.video_resolution.frame_width;
1314 rectangle.nHeight = drv_ctx.video_resolution.frame_height;
1315}
1316
Shalaj Jain273b3e02012-06-22 19:08:03 -07001317/* ======================================================================
1318FUNCTION
1319 omx_vdec::ComponentInit
1320
1321DESCRIPTION
1322 Initialize the component.
1323
1324PARAMETERS
1325 ctxt -- Context information related to the self.
1326 id -- Event identifier. This could be any of the following:
1327 1. Command completion event
1328 2. Buffer done callback event
1329 3. Frame done callback event
1330
1331RETURN VALUE
1332 None.
1333
1334========================================================================== */
1335OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1336{
1337
1338 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1339 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
1340 struct v4l2_fmtdesc fdesc;
1341 struct v4l2_format fmt;
1342 struct v4l2_requestbuffers bufreq;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001343 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001344 unsigned int alignment = 0,buffer_size = 0;
1345 int fds[2];
1346 int r,ret=0;
1347 bool codec_ambiguous = false;
1348 OMX_STRING device_name = "/dev/video32";
Vinay Kalia53fa6832012-10-11 17:55:30 -07001349 if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){
1350 struct v4l2_control control;
1351 secure_mode = true;
1352 arbitrary_bytes = false;
1353 role = "OMX.qcom.video.decoder.avc";
1354 }
1355
Shalaj Jain273b3e02012-06-22 19:08:03 -07001356 drv_ctx.video_driver_fd = open("/dev/video32", O_RDWR);
1357
1358 DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d",
1359 drv_ctx.video_driver_fd, errno);
1360
1361 if(drv_ctx.video_driver_fd == 0){
1362 drv_ctx.video_driver_fd = open(device_name, O_RDWR);
1363 }
1364
1365 if(drv_ctx.video_driver_fd < 0)
1366 {
1367 DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
1368 return OMX_ErrorInsufficientResources;
1369 }
1370 drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1371 drv_ctx.frame_rate.fps_denominator = 1;
1372
Vinay Kalia8a9c0372012-10-04 13:25:28 -07001373 ret = pthread_create(&async_thread_id,0,async_message_thread,this);
1374 if(ret < 0) {
1375 close(drv_ctx.video_driver_fd);
1376 DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
1377 return OMX_ErrorInsufficientResources;
1378 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001379
1380#ifdef INPUT_BUFFER_LOG
1381 strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
1382#endif
1383#ifdef OUTPUT_BUFFER_LOG
1384 outputBufferFile1 = fopen (outputfilename, "ab");
1385#endif
1386#ifdef OUTPUT_EXTRADATA_LOG
1387 outputExtradataFile = fopen (ouputextradatafilename, "ab");
1388#endif
1389
1390 // Copy the role information which provides the decoder kind
1391 strlcpy(drv_ctx.kind,role,128);
Vinay Kalia53fa6832012-10-11 17:55:30 -07001392
Shalaj Jain273b3e02012-06-22 19:08:03 -07001393 if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1394 OMX_MAX_STRINGNAME_SIZE))
1395 {
1396 strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1397 OMX_MAX_STRINGNAME_SIZE);
1398 drv_ctx.timestamp_adjust = true;
1399 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1400 eCompressionFormat = OMX_VIDEO_CodingMPEG4;
Praneeth Paladugu2a046832012-07-09 20:51:51 -07001401 output_capability=V4L2_PIX_FMT_MPEG4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001402 /*Initialize Start Code for MPEG4*/
1403 codec_type_parse = CODEC_TYPE_MPEG4;
1404 m_frame_parser.init_start_codes (codec_type_parse);
1405#ifdef INPUT_BUFFER_LOG
1406 strcat(inputfilename, "m4v");
1407#endif
1408 }
1409 else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1410 OMX_MAX_STRINGNAME_SIZE))
1411 {
1412 strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1413 OMX_MAX_STRINGNAME_SIZE);
1414 drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
Sachin Shah933b7d42012-06-25 21:27:33 -07001415 output_capability = V4L2_PIX_FMT_MPEG2;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001416 eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1417 /*Initialize Start Code for MPEG2*/
1418 codec_type_parse = CODEC_TYPE_MPEG2;
1419 m_frame_parser.init_start_codes (codec_type_parse);
1420#ifdef INPUT_BUFFER_LOG
1421 strcat(inputfilename, "mpg");
1422#endif
1423 }
1424 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1425 OMX_MAX_STRINGNAME_SIZE))
1426 {
1427 strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1428 DEBUG_PRINT_LOW("\n H263 Decoder selected");
1429 drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1430 eCompressionFormat = OMX_VIDEO_CodingH263;
Deva Ramasubramanian0868a002012-06-20 23:04:30 -07001431 output_capability = V4L2_PIX_FMT_H263;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001432 codec_type_parse = CODEC_TYPE_H263;
1433 m_frame_parser.init_start_codes (codec_type_parse);
1434#ifdef INPUT_BUFFER_LOG
1435 strcat(inputfilename, "263");
1436#endif
1437 }
1438 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1439 OMX_MAX_STRINGNAME_SIZE))
1440 {
1441 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1442 DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
1443 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1444 output_capability = V4L2_PIX_FMT_DIVX_311;
1445 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1446 codec_type_parse = CODEC_TYPE_DIVX;
1447 m_frame_parser.init_start_codes (codec_type_parse);
1448
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001449 eRet = createDivxDrmContext();
1450 if (eRet != OMX_ErrorNone) {
1451 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1452 return eRet;
1453 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001454 }
1455 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1456 OMX_MAX_STRINGNAME_SIZE))
1457 {
1458 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1459 DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
1460 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1461 output_capability = V4L2_PIX_FMT_DIVX;
1462 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1463 codec_type_parse = CODEC_TYPE_DIVX;
1464 codec_ambiguous = true;
1465 m_frame_parser.init_start_codes (codec_type_parse);
1466
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001467 eRet = createDivxDrmContext();
1468 if (eRet != OMX_ErrorNone) {
1469 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1470 return eRet;
1471 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001472 }
1473 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1474 OMX_MAX_STRINGNAME_SIZE))
1475 {
1476 strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1477 DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
1478 drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1479 output_capability = V4L2_PIX_FMT_DIVX;
1480 eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1481 codec_type_parse = CODEC_TYPE_DIVX;
1482 codec_ambiguous = true;
1483 m_frame_parser.init_start_codes (codec_type_parse);
1484
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08001485 eRet = createDivxDrmContext();
1486 if (eRet != OMX_ErrorNone) {
1487 DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1488 return eRet;
1489 }
1490
Shalaj Jain273b3e02012-06-22 19:08:03 -07001491 }
1492 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1493 OMX_MAX_STRINGNAME_SIZE))
1494 {
1495 strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1496 drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1497 output_capability=V4L2_PIX_FMT_H264;
1498 eCompressionFormat = OMX_VIDEO_CodingAVC;
1499 codec_type_parse = CODEC_TYPE_H264;
1500 m_frame_parser.init_start_codes (codec_type_parse);
1501 m_frame_parser.init_nal_length(nal_length);
1502#ifdef INPUT_BUFFER_LOG
1503 strcat(inputfilename, "264");
1504#endif
1505 }
1506 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1507 OMX_MAX_STRINGNAME_SIZE))
1508 {
1509 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1510 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1511 eCompressionFormat = OMX_VIDEO_CodingWMV;
1512 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugueed23ec2012-07-09 21:02:39 -07001513 output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001514 m_frame_parser.init_start_codes (codec_type_parse);
1515#ifdef INPUT_BUFFER_LOG
1516 strcat(inputfilename, "vc1");
1517#endif
1518 }
1519 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1520 OMX_MAX_STRINGNAME_SIZE))
1521 {
1522 strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1523 drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1524 eCompressionFormat = OMX_VIDEO_CodingWMV;
1525 codec_type_parse = CODEC_TYPE_VC1;
Praneeth Paladugu226667c2012-09-12 16:42:30 -07001526 output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001527 m_frame_parser.init_start_codes (codec_type_parse);
1528#ifdef INPUT_BUFFER_LOG
1529 strcat(inputfilename, "vc1");
1530#endif
1531 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07001532 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \
1533 OMX_MAX_STRINGNAME_SIZE))
1534 {
1535 strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
1536 output_capability=V4L2_PIX_FMT_VP8;
1537 eCompressionFormat = OMX_VIDEO_CodingVPX;
1538 codec_type_parse = CODEC_TYPE_VP8;
1539 arbitrary_bytes = false;
1540 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001541 else
1542 {
1543 DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1544 eRet = OMX_ErrorInvalidComponentName;
1545 }
1546#ifdef INPUT_BUFFER_LOG
1547 inputBufferFile1 = fopen (inputfilename, "ab");
1548#endif
1549 if (eRet == OMX_ErrorNone)
1550 {
1551
Vinay Kaliada4f4422013-01-09 10:45:03 -08001552 drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
1553 OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1554 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
1555 if (!client_buffers.set_color_format(dest_color_format)) {
1556 DEBUG_PRINT_ERROR("\n Setting color format failed");
1557 eRet = OMX_ErrorInsufficientResources;
1558 }
1559
Shalaj Jain273b3e02012-06-22 19:08:03 -07001560 capture_capability= V4L2_PIX_FMT_NV12;
Vinay Kalia85793762012-06-14 19:12:34 -07001561 ret = subscribe_to_events(drv_ctx.video_driver_fd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001562 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001563 DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n");
1564 return OMX_ErrorInsufficientResources;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001565 }
1566
1567 struct v4l2_capability cap;
1568 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
1569 if (ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001570 DEBUG_PRINT_ERROR("Failed to query capabilities\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001571 /*TODO: How to handle this case */
1572 } else {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001573 DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
Shalaj Jain273b3e02012-06-22 19:08:03 -07001574 " version = %d, capabilities = %x\n", cap.driver, cap.card,
1575 cap.bus_info, cap.version, cap.capabilities);
1576 }
1577 ret=0;
1578 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1579 fdesc.index=0;
1580 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001581 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001582 fdesc.pixelformat, fdesc.flags);
1583 fdesc.index++;
1584 }
1585 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1586 fdesc.index=0;
1587 while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
1588
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001589 DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
Shalaj Jain273b3e02012-06-22 19:08:03 -07001590 fdesc.pixelformat, fdesc.flags);
1591 fdesc.index++;
1592 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08001593 update_resolution(320, 240);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001594 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1595 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1596 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
1597 fmt.fmt.pix_mp.pixelformat = output_capability;
1598 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1599 if (ret) {
1600 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001601 DEBUG_PRINT_ERROR("Failed to set format on output port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001602 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001603 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001604 if (codec_ambiguous) {
1605 if (output_capability == V4L2_PIX_FMT_DIVX) {
1606 struct v4l2_control divx_ctrl;
1607
1608 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001609 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001610 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001611 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001612 } else {
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001613 divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001614 }
1615
Praneeth Paladugub1ed45c2012-10-08 18:23:11 -07001616 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
Praneeth Paladuguf54dd1b2012-09-18 12:18:22 -07001617 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001618 if (ret) {
1619 DEBUG_PRINT_ERROR("Failed to set divx version\n");
1620 }
1621 } else {
1622 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
1623 }
1624 }
1625
1626 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1627 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
1628 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07001629 fmt.fmt.pix_mp.pixelformat = capture_capability;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001630 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
1631 if (ret) {
1632 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001633 DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001634 }
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001635 DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
Vinay Kalia53fa6832012-10-11 17:55:30 -07001636 if(secure_mode){
Vinay Kalia53fa6832012-10-11 17:55:30 -07001637 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
1638 control.value = 1;
1639 DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
1640 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
1641 if (ret) {
1642 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
1643 close(drv_ctx.video_driver_fd);
1644 return OMX_ErrorInsufficientResources;
1645 }
1646 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001647
1648 /*Get the Buffer requirements for input and output ports*/
1649 drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1650 drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
Vinay Kalia53fa6832012-10-11 17:55:30 -07001651 if (secure_mode) {
1652 drv_ctx.op_buf.alignment=SZ_1M;
1653 drv_ctx.ip_buf.alignment=SZ_1M;
1654 } else {
1655 drv_ctx.op_buf.alignment=SZ_4K;
1656 drv_ctx.ip_buf.alignment=SZ_4K;
1657 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001658 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1659 drv_ctx.extradata = 0;
Praneeth Paladugu42a83da2012-12-11 12:21:07 -08001660 drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1661 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
1662 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
1663 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001664 drv_ctx.idr_only_decoding = 0;
1665
Vinay Kalia5713bb32013-01-16 18:39:59 -08001666 m_state = OMX_StateLoaded;
Shalaj Jain273b3e02012-06-22 19:08:03 -07001667#ifdef DEFAULT_EXTRADATA
Vinay Kalia5713bb32013-01-16 18:39:59 -08001668 if (eRet == OMX_ErrorNone && !secure_mode)
1669 enable_extradata(DEFAULT_EXTRADATA, true, true);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001670#endif
Vinay Kalia5713bb32013-01-16 18:39:59 -08001671 eRet=get_buffer_req(&drv_ctx.ip_buf);
1672 DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
1673 get_buffer_req(&drv_ctx.op_buf);
Shalaj Jain273b3e02012-06-22 19:08:03 -07001674 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
1675 {
1676 if (m_frame_parser.mutils == NULL)
1677 {
1678 m_frame_parser.mutils = new H264_Utils();
1679
1680 if (m_frame_parser.mutils == NULL)
1681 {
1682 DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1683 eRet = OMX_ErrorInsufficientResources;
1684 }
1685 else
1686 {
1687 h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
1688 h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
1689 h264_scratch.nFilledLen = 0;
1690 h264_scratch.nOffset = 0;
1691
1692 if (h264_scratch.pBuffer == NULL)
1693 {
1694 DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1695 return OMX_ErrorInsufficientResources;
1696 }
1697 m_frame_parser.mutils->initialize_frame_checking_environment();
1698 m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1699 }
1700 }
1701
1702 h264_parser = new h264_stream_parser();
1703 if (!h264_parser)
1704 {
1705 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1706 eRet = OMX_ErrorInsufficientResources;
1707 }
1708 }
1709
1710 if(pipe(fds))
1711 {
1712 DEBUG_PRINT_ERROR("pipe creation failed\n");
1713 eRet = OMX_ErrorInsufficientResources;
1714 }
1715 else
1716 {
1717 int temp1[2];
1718 if(fds[0] == 0 || fds[1] == 0)
1719 {
1720 if (pipe (temp1))
1721 {
1722 DEBUG_PRINT_ERROR("pipe creation failed\n");
1723 return OMX_ErrorInsufficientResources;
1724 }
1725 //close (fds[0]);
1726 //close (fds[1]);
1727 fds[0] = temp1 [0];
1728 fds[1] = temp1 [1];
1729 }
1730 m_pipe_in = fds[0];
1731 m_pipe_out = fds[1];
1732 r = pthread_create(&msg_thread_id,0,message_thread,this);
1733
1734 if(r < 0)
1735 {
1736 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1737 eRet = OMX_ErrorInsufficientResources;
1738 }
1739 }
1740 }
1741
1742 if (eRet != OMX_ErrorNone)
1743 {
1744 DEBUG_PRINT_ERROR("\n Component Init Failed");
1745 DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
1746 (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
1747 NULL);
1748 DEBUG_PRINT_HIGH("\n Calling close() on Video Driver");
1749 close (drv_ctx.video_driver_fd);
1750 drv_ctx.video_driver_fd = -1;
1751 }
1752 else
1753 {
1754 DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
1755 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07001756 //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1757 return eRet;
1758}
1759
1760/* ======================================================================
1761FUNCTION
1762 omx_vdec::GetComponentVersion
1763
1764DESCRIPTION
1765 Returns the component version.
1766
1767PARAMETERS
1768 TBD.
1769
1770RETURN VALUE
1771 OMX_ErrorNone.
1772
1773========================================================================== */
1774OMX_ERRORTYPE omx_vdec::get_component_version
1775 (
1776 OMX_IN OMX_HANDLETYPE hComp,
1777 OMX_OUT OMX_STRING componentName,
1778 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1779 OMX_OUT OMX_VERSIONTYPE* specVersion,
1780 OMX_OUT OMX_UUIDTYPE* componentUUID
1781 )
1782{
1783 if(m_state == OMX_StateInvalid)
1784 {
1785 DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1786 return OMX_ErrorInvalidState;
1787 }
1788 /* TBD -- Return the proper version */
1789 if (specVersion)
1790 {
1791 specVersion->nVersion = OMX_SPEC_VERSION;
1792 }
1793 return OMX_ErrorNone;
1794}
1795/* ======================================================================
1796FUNCTION
1797 omx_vdec::SendCommand
1798
1799DESCRIPTION
1800 Returns zero if all the buffers released..
1801
1802PARAMETERS
1803 None.
1804
1805RETURN VALUE
1806 true/false
1807
1808========================================================================== */
1809OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
1810 OMX_IN OMX_COMMANDTYPE cmd,
1811 OMX_IN OMX_U32 param1,
1812 OMX_IN OMX_PTR cmdData
1813 )
1814{
1815 DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
1816 if(m_state == OMX_StateInvalid)
1817 {
1818 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
1819 return OMX_ErrorInvalidState;
1820 }
1821 if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
1822 && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL)
1823 {
1824 DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
1825 "to invalid port: %d", param1);
1826 return OMX_ErrorBadPortIndex;
1827 }
1828 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1829 sem_wait(&m_cmd_lock);
1830 DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
1831 return OMX_ErrorNone;
1832}
1833
1834/* ======================================================================
1835FUNCTION
1836 omx_vdec::SendCommand
1837
1838DESCRIPTION
1839 Returns zero if all the buffers released..
1840
1841PARAMETERS
1842 None.
1843
1844RETURN VALUE
1845 true/false
1846
1847========================================================================== */
1848OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1849 OMX_IN OMX_COMMANDTYPE cmd,
1850 OMX_IN OMX_U32 param1,
1851 OMX_IN OMX_PTR cmdData
1852 )
1853{
1854 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1855 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1856 int bFlag = 1,sem_posted = 0,ret=0;
1857
1858 DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
1859 DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
1860 m_state, eState);
1861
1862 if(cmd == OMX_CommandStateSet)
1863 {
1864 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
1865 DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
1866 /***************************/
1867 /* Current State is Loaded */
1868 /***************************/
1869 if(m_state == OMX_StateLoaded)
1870 {
1871 if(eState == OMX_StateIdle)
1872 {
1873 //if all buffers are allocated or all ports disabled
1874 if(allocate_done() ||
1875 (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
1876 {
1877 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
1878 }
1879 else
1880 {
1881 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
1882 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1883 // Skip the event notification
1884 bFlag = 0;
1885 }
1886 }
1887 /* Requesting transition from Loaded to Loaded */
1888 else if(eState == OMX_StateLoaded)
1889 {
1890 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
1891 post_event(OMX_EventError,OMX_ErrorSameState,\
1892 OMX_COMPONENT_GENERATE_EVENT);
1893 eRet = OMX_ErrorSameState;
1894 }
1895 /* Requesting transition from Loaded to WaitForResources */
1896 else if(eState == OMX_StateWaitForResources)
1897 {
1898 /* Since error is None , we will post an event
1899 at the end of this function definition */
1900 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
1901 }
1902 /* Requesting transition from Loaded to Executing */
1903 else if(eState == OMX_StateExecuting)
1904 {
1905 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1906 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1907 OMX_COMPONENT_GENERATE_EVENT);
1908 eRet = OMX_ErrorIncorrectStateTransition;
1909 }
1910 /* Requesting transition from Loaded to Pause */
1911 else if(eState == OMX_StatePause)
1912 {
1913 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1914 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1915 OMX_COMPONENT_GENERATE_EVENT);
1916 eRet = OMX_ErrorIncorrectStateTransition;
1917 }
1918 /* Requesting transition from Loaded to Invalid */
1919 else if(eState == OMX_StateInvalid)
1920 {
1921 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1922 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1923 eRet = OMX_ErrorInvalidState;
1924 }
1925 else
1926 {
1927 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1928 eState);
1929 eRet = OMX_ErrorBadParameter;
1930 }
1931 }
1932
1933 /***************************/
1934 /* Current State is IDLE */
1935 /***************************/
1936 else if(m_state == OMX_StateIdle)
1937 {
1938 if(eState == OMX_StateLoaded)
1939 {
1940 if(release_done())
1941 {
1942 /*
1943 Since error is None , we will post an event at the end
1944 of this function definition
1945 */
1946 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
1947 }
1948 else
1949 {
1950 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
1951 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1952 // Skip the event notification
1953 bFlag = 0;
1954 }
1955 }
1956 /* Requesting transition from Idle to Executing */
1957 else if(eState == OMX_StateExecuting)
1958 {
1959 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1960 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1961 bFlag = 1;
1962 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
1963 m_state=OMX_StateExecuting;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07001964 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07001965 }
1966 /* Requesting transition from Idle to Idle */
1967 else if(eState == OMX_StateIdle)
1968 {
1969 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
1970 post_event(OMX_EventError,OMX_ErrorSameState,\
1971 OMX_COMPONENT_GENERATE_EVENT);
1972 eRet = OMX_ErrorSameState;
1973 }
1974 /* Requesting transition from Idle to WaitForResources */
1975 else if(eState == OMX_StateWaitForResources)
1976 {
1977 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
1978 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1979 OMX_COMPONENT_GENERATE_EVENT);
1980 eRet = OMX_ErrorIncorrectStateTransition;
1981 }
1982 /* Requesting transition from Idle to Pause */
1983 else if(eState == OMX_StatePause)
1984 {
1985 /*To pause the Video core we need to start the driver*/
1986 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
1987 NULL) < */0)
1988 {
1989 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
1990 omx_report_error ();
1991 eRet = OMX_ErrorHardware;
1992 }
1993 else
1994 {
1995 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1996 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
1997 bFlag = 0;
1998 }
1999 }
2000 /* Requesting transition from Idle to Invalid */
2001 else if(eState == OMX_StateInvalid)
2002 {
2003 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
2004 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2005 eRet = OMX_ErrorInvalidState;
2006 }
2007 else
2008 {
2009 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
2010 eRet = OMX_ErrorBadParameter;
2011 }
2012 }
2013
2014 /******************************/
2015 /* Current State is Executing */
2016 /******************************/
2017 else if(m_state == OMX_StateExecuting)
2018 {
2019 DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
2020 /* Requesting transition from Executing to Idle */
2021 if(eState == OMX_StateIdle)
Vinay Kalia85793762012-06-14 19:12:34 -07002022 {
2023 /* Since error is None , we will post an event
2024 at the end of this function definition
2025 */
2026 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002027 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
Vinay Kalia85793762012-06-14 19:12:34 -07002028 if(!sem_posted)
2029 {
2030 sem_posted = 1;
2031 sem_post (&m_cmd_lock);
2032 execute_omx_flush(OMX_ALL);
2033 }
Praneeth Paladugud02d20e2012-08-30 19:40:57 -07002034 bFlag = 0;
Vinay Kalia85793762012-06-14 19:12:34 -07002035 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002036 /* Requesting transition from Executing to Paused */
2037 else if(eState == OMX_StatePause)
2038 {
2039 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
2040 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_PAUSE,
2041 NULL) < */0)
2042 {
2043 DEBUG_PRINT_ERROR("\n Error In Pause State");
2044 post_event(OMX_EventError,OMX_ErrorHardware,\
2045 OMX_COMPONENT_GENERATE_EVENT);
2046 eRet = OMX_ErrorHardware;
2047 }
2048 else
2049 {
2050 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
2051 DEBUG_PRINT_LOW("send_command_proxy(): Executing-->Pause\n");
2052 bFlag = 0;
2053 }
2054 }
2055 /* Requesting transition from Executing to Loaded */
2056 else if(eState == OMX_StateLoaded)
2057 {
2058 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
2059 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2060 OMX_COMPONENT_GENERATE_EVENT);
2061 eRet = OMX_ErrorIncorrectStateTransition;
2062 }
2063 /* Requesting transition from Executing to WaitForResources */
2064 else if(eState == OMX_StateWaitForResources)
2065 {
2066 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
2067 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2068 OMX_COMPONENT_GENERATE_EVENT);
2069 eRet = OMX_ErrorIncorrectStateTransition;
2070 }
2071 /* Requesting transition from Executing to Executing */
2072 else if(eState == OMX_StateExecuting)
2073 {
2074 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
2075 post_event(OMX_EventError,OMX_ErrorSameState,\
2076 OMX_COMPONENT_GENERATE_EVENT);
2077 eRet = OMX_ErrorSameState;
2078 }
2079 /* Requesting transition from Executing to Invalid */
2080 else if(eState == OMX_StateInvalid)
2081 {
2082 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
2083 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2084 eRet = OMX_ErrorInvalidState;
2085 }
2086 else
2087 {
2088 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
2089 eRet = OMX_ErrorBadParameter;
2090 }
2091 }
2092 /***************************/
2093 /* Current State is Pause */
2094 /***************************/
2095 else if(m_state == OMX_StatePause)
2096 {
2097 /* Requesting transition from Pause to Executing */
2098 if(eState == OMX_StateExecuting)
2099 {
2100 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
2101 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_RESUME,
2102 NULL) < */0)
2103 {
2104 DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_RESUME failed");
2105 post_event(OMX_EventError,OMX_ErrorHardware,\
2106 OMX_COMPONENT_GENERATE_EVENT);
2107 eRet = OMX_ErrorHardware;
2108 }
2109 else
2110 {
2111 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
2112 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
2113 post_event (NULL,VDEC_S_SUCCESS,\
2114 OMX_COMPONENT_GENERATE_RESUME_DONE);
2115 bFlag = 0;
2116 }
2117 }
2118 /* Requesting transition from Pause to Idle */
2119 else if(eState == OMX_StateIdle)
2120 {
2121 /* Since error is None , we will post an event
2122 at the end of this function definition */
2123 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
2124 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
2125 if(!sem_posted)
2126 {
2127 sem_posted = 1;
2128 sem_post (&m_cmd_lock);
2129 execute_omx_flush(OMX_ALL);
2130 }
2131 bFlag = 0;
2132 }
2133 /* Requesting transition from Pause to loaded */
2134 else if(eState == OMX_StateLoaded)
2135 {
2136 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
2137 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2138 OMX_COMPONENT_GENERATE_EVENT);
2139 eRet = OMX_ErrorIncorrectStateTransition;
2140 }
2141 /* Requesting transition from Pause to WaitForResources */
2142 else if(eState == OMX_StateWaitForResources)
2143 {
2144 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
2145 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2146 OMX_COMPONENT_GENERATE_EVENT);
2147 eRet = OMX_ErrorIncorrectStateTransition;
2148 }
2149 /* Requesting transition from Pause to Pause */
2150 else if(eState == OMX_StatePause)
2151 {
2152 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
2153 post_event(OMX_EventError,OMX_ErrorSameState,\
2154 OMX_COMPONENT_GENERATE_EVENT);
2155 eRet = OMX_ErrorSameState;
2156 }
2157 /* Requesting transition from Pause to Invalid */
2158 else if(eState == OMX_StateInvalid)
2159 {
2160 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
2161 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2162 eRet = OMX_ErrorInvalidState;
2163 }
2164 else
2165 {
2166 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
2167 eRet = OMX_ErrorBadParameter;
2168 }
2169 }
2170 /***************************/
2171 /* Current State is WaitForResources */
2172 /***************************/
2173 else if(m_state == OMX_StateWaitForResources)
2174 {
2175 /* Requesting transition from WaitForResources to Loaded */
2176 if(eState == OMX_StateLoaded)
2177 {
2178 /* Since error is None , we will post an event
2179 at the end of this function definition */
2180 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
2181 }
2182 /* Requesting transition from WaitForResources to WaitForResources */
2183 else if (eState == OMX_StateWaitForResources)
2184 {
2185 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2186 post_event(OMX_EventError,OMX_ErrorSameState,
2187 OMX_COMPONENT_GENERATE_EVENT);
2188 eRet = OMX_ErrorSameState;
2189 }
2190 /* Requesting transition from WaitForResources to Executing */
2191 else if(eState == OMX_StateExecuting)
2192 {
2193 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2194 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2195 OMX_COMPONENT_GENERATE_EVENT);
2196 eRet = OMX_ErrorIncorrectStateTransition;
2197 }
2198 /* Requesting transition from WaitForResources to Pause */
2199 else if(eState == OMX_StatePause)
2200 {
2201 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2202 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2203 OMX_COMPONENT_GENERATE_EVENT);
2204 eRet = OMX_ErrorIncorrectStateTransition;
2205 }
2206 /* Requesting transition from WaitForResources to Invalid */
2207 else if(eState == OMX_StateInvalid)
2208 {
2209 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2210 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2211 eRet = OMX_ErrorInvalidState;
2212 }
2213 /* Requesting transition from WaitForResources to Loaded -
2214 is NOT tested by Khronos TS */
2215
2216 }
2217 else
2218 {
2219 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2220 eRet = OMX_ErrorBadParameter;
2221 }
2222 }
2223 /********************************/
2224 /* Current State is Invalid */
2225 /*******************************/
2226 else if(m_state == OMX_StateInvalid)
2227 {
2228 /* State Transition from Inavlid to any state */
2229 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
2230 || OMX_StateIdle || OMX_StateExecuting
2231 || OMX_StatePause || OMX_StateInvalid))
2232 {
2233 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2234 post_event(OMX_EventError,OMX_ErrorInvalidState,\
2235 OMX_COMPONENT_GENERATE_EVENT);
2236 eRet = OMX_ErrorInvalidState;
2237 }
2238 }
2239 else if (cmd == OMX_CommandFlush)
2240 {
2241 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
2242 "with param1: %d", param1);
2243 if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2244 {
2245 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2246 }
2247 if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1)
2248 {
2249 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2250 }
2251 if (!sem_posted){
2252 sem_posted = 1;
2253 DEBUG_PRINT_LOW("\n Set the Semaphore");
2254 sem_post (&m_cmd_lock);
2255 execute_omx_flush(param1);
2256 }
2257 bFlag = 0;
2258 }
2259 else if ( cmd == OMX_CommandPortEnable)
2260 {
2261 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
2262 "with param1: %d", param1);
2263 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2264 {
2265 m_inp_bEnabled = OMX_TRUE;
2266
2267 if( (m_state == OMX_StateLoaded &&
2268 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2269 || allocate_input_done())
2270 {
2271 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2272 OMX_COMPONENT_GENERATE_EVENT);
2273 }
2274 else
2275 {
2276 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2277 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2278 // Skip the event notification
2279 bFlag = 0;
2280 }
2281 }
2282 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2283 {
2284 DEBUG_PRINT_LOW("\n Enable output Port command recieved");
2285 m_out_bEnabled = OMX_TRUE;
2286
2287 if( (m_state == OMX_StateLoaded &&
2288 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2289 || (allocate_output_done()))
2290 {
2291 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2292 OMX_COMPONENT_GENERATE_EVENT);
2293
2294 }
2295 else
2296 {
2297 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
2298 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2299 // Skip the event notification
2300 bFlag = 0;
2301 }
2302 }
2303 }
2304 else if (cmd == OMX_CommandPortDisable)
2305 {
2306 DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
2307 "with param1: %d", param1);
2308 if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
2309 {
2310 m_inp_bEnabled = OMX_FALSE;
2311 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2312 && release_input_done())
2313 {
2314 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2315 OMX_COMPONENT_GENERATE_EVENT);
2316 }
2317 else
2318 {
2319 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2320 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2321 {
2322 if(!sem_posted)
2323 {
2324 sem_posted = 1;
2325 sem_post (&m_cmd_lock);
2326 }
2327 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2328 }
2329
2330 // Skip the event notification
2331 bFlag = 0;
2332 }
2333 }
2334 if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
2335 {
2336 m_out_bEnabled = OMX_FALSE;
2337 DEBUG_PRINT_LOW("\n Disable output Port command recieved");
2338 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2339 && release_output_done())
2340 {
2341 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2342 OMX_COMPONENT_GENERATE_EVENT);
2343 }
2344 else
2345 {
2346 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2347 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
2348 {
2349 if (!sem_posted)
2350 {
2351 sem_posted = 1;
2352 sem_post (&m_cmd_lock);
2353 }
2354 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2355 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2356 }
2357 // Skip the event notification
2358 bFlag = 0;
2359
2360 }
2361 }
2362 }
2363 else
2364 {
2365 DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2366 eRet = OMX_ErrorNotImplemented;
2367 }
2368 if(eRet == OMX_ErrorNone && bFlag)
2369 {
2370 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2371 }
2372 if(!sem_posted)
2373 {
2374 sem_post(&m_cmd_lock);
2375 }
2376
2377 return eRet;
2378}
2379
2380/* ======================================================================
2381FUNCTION
2382 omx_vdec::ExecuteOmxFlush
2383
2384DESCRIPTION
2385 Executes the OMX flush.
2386
2387PARAMETERS
2388 flushtype - input flush(1)/output flush(0)/ both.
2389
2390RETURN VALUE
2391 true/false
2392
2393========================================================================== */
2394bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2395{
Shalaj Jain273b3e02012-06-22 19:08:03 -07002396 bool bRet = false;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002397 struct v4l2_plane plane;
2398 struct v4l2_buffer v4l2_buf ={0};
2399 struct v4l2_decoder_cmd dec;
2400 DEBUG_PRINT_LOW("in %s", __func__);
2401 dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002402 switch (flushType)
2403 {
2404 case OMX_CORE_INPUT_PORT_INDEX:
2405 input_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002406 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002407 break;
2408 case OMX_CORE_OUTPUT_PORT_INDEX:
2409 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002410 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002411 break;
2412 default:
2413 input_flush_progress = true;
2414 output_flush_progress = true;
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002415 dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT |
2416 V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002417 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002418
2419 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
Shalaj Jain273b3e02012-06-22 19:08:03 -07002420 {
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002421 DEBUG_PRINT_ERROR("\n Flush Port (%d) Failed ", flushType);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002422 bRet = false;
2423 }
Deva Ramasubramanian03c9c742012-07-02 15:00:15 -07002424
Shalaj Jain273b3e02012-06-22 19:08:03 -07002425 return bRet;
2426}
2427/*=========================================================================
2428FUNCTION : execute_output_flush
2429
2430DESCRIPTION
2431 Executes the OMX flush at OUTPUT PORT.
2432
2433PARAMETERS
2434 None.
2435
2436RETURN VALUE
2437 true/false
2438==========================================================================*/
2439bool omx_vdec::execute_output_flush()
2440{
2441 unsigned p1 = 0; // Parameter - 1
2442 unsigned p2 = 0; // Parameter - 2
2443 unsigned ident = 0;
2444 bool bRet = true;
2445
2446 /*Generate FBD for all Buffers in the FTBq*/
2447 pthread_mutex_lock(&m_lock);
2448 DEBUG_PRINT_LOW("\n Initiate Output Flush");
2449 while (m_ftb_q.m_size)
2450 {
2451 DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
2452 m_ftb_q.m_size,pending_output_buffers);
2453 m_ftb_q.pop_entry(&p1,&p2,&ident);
2454 DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
Vinay Kaliada4f4422013-01-09 10:45:03 -08002455 if(ident == m_fill_output_msg )
Shalaj Jain273b3e02012-06-22 19:08:03 -07002456 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08002457 m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002458 }
2459 else if (ident == OMX_COMPONENT_GENERATE_FBD)
2460 {
2461 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2462 }
2463 }
2464 pthread_mutex_unlock(&m_lock);
2465 output_flush_progress = false;
2466
2467 if (arbitrary_bytes)
2468 {
2469 prev_ts = LLONG_MAX;
2470 rst_prev_ts = true;
2471 }
2472 DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2473 return bRet;
2474}
2475/*=========================================================================
2476FUNCTION : execute_input_flush
2477
2478DESCRIPTION
2479 Executes the OMX flush at INPUT PORT.
2480
2481PARAMETERS
2482 None.
2483
2484RETURN VALUE
2485 true/false
2486==========================================================================*/
2487bool omx_vdec::execute_input_flush()
2488{
2489 unsigned i =0;
2490 unsigned p1 = 0; // Parameter - 1
2491 unsigned p2 = 0; // Parameter - 2
2492 unsigned ident = 0;
2493 bool bRet = true;
2494
2495 /*Generate EBD for all Buffers in the ETBq*/
2496 DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
2497
2498 pthread_mutex_lock(&m_lock);
2499 DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
2500 while (m_etb_q.m_size)
2501 {
2502 m_etb_q.pop_entry(&p1,&p2,&ident);
2503
2504 if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2505 {
2506 DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2507 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2508 }
2509 else if(ident == OMX_COMPONENT_GENERATE_ETB)
2510 {
2511 pending_input_buffers++;
2512 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2513 (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2514 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2515 }
2516 else if (ident == OMX_COMPONENT_GENERATE_EBD)
2517 {
2518 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2519 (OMX_BUFFERHEADERTYPE *)p1);
2520 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2521 }
2522 }
2523 time_stamp_dts.flush_timestamp();
2524 /*Check if Heap Buffers are to be flushed*/
2525 if (arbitrary_bytes)
2526 {
2527 DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
2528 h264_scratch.nFilledLen = 0;
2529 nal_count = 0;
2530 look_ahead_nal = false;
2531 frame_count = 0;
2532 h264_last_au_ts = LLONG_MAX;
2533 h264_last_au_flags = 0;
2534 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2535 m_demux_entries = 0;
2536 DEBUG_PRINT_LOW("\n Initialize parser");
2537 if (m_frame_parser.mutils)
2538 {
2539 m_frame_parser.mutils->initialize_frame_checking_environment();
2540 }
2541
2542 while (m_input_pending_q.m_size)
2543 {
2544 m_input_pending_q.pop_entry(&p1,&p2,&ident);
2545 m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2546 }
2547
2548 if (psource_frame)
2549 {
2550 m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2551 psource_frame = NULL;
2552 }
2553
2554 if (pdest_frame)
2555 {
2556 pdest_frame->nFilledLen = 0;
2557 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
2558 pdest_frame = NULL;
2559 }
2560 m_frame_parser.flush();
2561 }
2562 pthread_mutex_unlock(&m_lock);
2563 input_flush_progress = false;
2564 if (!arbitrary_bytes)
2565 {
2566 prev_ts = LLONG_MAX;
2567 rst_prev_ts = true;
2568 }
2569#ifdef _ANDROID_
2570 if (m_debug_timestamp)
2571 {
2572 m_timestamp_list.reset_ts_list();
2573 }
2574#endif
2575 DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2576 return bRet;
2577}
2578
2579
2580/* ======================================================================
2581FUNCTION
2582 omx_vdec::SendCommandEvent
2583
2584DESCRIPTION
2585 Send the event to decoder pipe. This is needed to generate the callbacks
2586 in decoder thread context.
2587
2588PARAMETERS
2589 None.
2590
2591RETURN VALUE
2592 true/false
2593
2594========================================================================== */
2595bool omx_vdec::post_event(unsigned int p1,
2596 unsigned int p2,
2597 unsigned int id)
2598{
2599 bool bRet = false;
2600
2601
2602 pthread_mutex_lock(&m_lock);
2603
Vinay Kaliada4f4422013-01-09 10:45:03 -08002604 if (id == m_fill_output_msg ||
Shalaj Jain273b3e02012-06-22 19:08:03 -07002605 id == OMX_COMPONENT_GENERATE_FBD)
2606 {
2607 m_ftb_q.insert_entry(p1,p2,id);
2608 }
2609 else if (id == OMX_COMPONENT_GENERATE_ETB ||
2610 id == OMX_COMPONENT_GENERATE_EBD ||
2611 id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
2612 {
2613 m_etb_q.insert_entry(p1,p2,id);
2614 }
2615 else
2616 {
2617 m_cmd_q.insert_entry(p1,p2,id);
2618 }
2619
2620 bRet = true;
2621 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
2622 post_message(this, id);
2623
2624 pthread_mutex_unlock(&m_lock);
2625
2626 return bRet;
2627}
2628
2629OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2630{
Vinay Kaliada4f4422013-01-09 10:45:03 -08002631 OMX_ERRORTYPE eRet = OMX_ErrorNoMore;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002632 if(!profileLevelType)
2633 return OMX_ErrorBadParameter;
2634
2635 if(profileLevelType->nPortIndex == 0) {
2636 if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
2637 {
2638 if (profileLevelType->nProfileIndex == 0)
2639 {
2640 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2641 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2642
2643 }
2644 else if (profileLevelType->nProfileIndex == 1)
2645 {
2646 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2647 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2648 }
2649 else if(profileLevelType->nProfileIndex == 2)
2650 {
2651 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2652 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
2653 }
2654 else
2655 {
2656 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
2657 profileLevelType->nProfileIndex);
2658 eRet = OMX_ErrorNoMore;
2659 }
2660 }
2661 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)))
2662 {
2663 if (profileLevelType->nProfileIndex == 0)
2664 {
2665 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2666 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
2667 }
2668 else
2669 {
2670 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
2671 eRet = OMX_ErrorNoMore;
2672 }
2673 }
2674 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
2675 {
2676 if (profileLevelType->nProfileIndex == 0)
2677 {
2678 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2679 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2680 }
2681 else if(profileLevelType->nProfileIndex == 1)
2682 {
2683 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2684 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
2685 }
2686 else
2687 {
2688 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
2689 eRet = OMX_ErrorNoMore;
2690 }
2691 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07002692 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
2693 {
2694 eRet = OMX_ErrorNoMore;
2695 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07002696 else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
2697 {
2698 if (profileLevelType->nProfileIndex == 0)
2699 {
2700 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2701 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2702 }
2703 else if(profileLevelType->nProfileIndex == 1)
2704 {
2705 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2706 profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL;
2707 }
2708 else
2709 {
2710 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
2711 eRet = OMX_ErrorNoMore;
2712 }
2713 }
2714 }
2715 else
2716 {
2717 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
2718 eRet = OMX_ErrorBadPortIndex;
2719 }
2720 return eRet;
2721}
2722
2723/* ======================================================================
2724FUNCTION
2725 omx_vdec::GetParameter
2726
2727DESCRIPTION
2728 OMX Get Parameter method implementation
2729
2730PARAMETERS
2731 <TBD>.
2732
2733RETURN VALUE
2734 Error None if successful.
2735
2736========================================================================== */
2737OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
2738 OMX_IN OMX_INDEXTYPE paramIndex,
2739 OMX_INOUT OMX_PTR paramData)
2740{
2741 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2742
2743 DEBUG_PRINT_LOW("get_parameter: \n");
2744 if(m_state == OMX_StateInvalid)
2745 {
2746 DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2747 return OMX_ErrorInvalidState;
2748 }
2749 if(paramData == NULL)
2750 {
2751 DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
2752 return OMX_ErrorBadParameter;
2753 }
2754 switch(paramIndex)
2755 {
2756 case OMX_IndexParamPortDefinition:
2757 {
2758 OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2759 (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2760 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
2761 eRet = update_portdef(portDefn);
2762 if (eRet == OMX_ErrorNone)
2763 m_port_def = *portDefn;
2764 break;
2765 }
2766 case OMX_IndexParamVideoInit:
2767 {
2768 OMX_PORT_PARAM_TYPE *portParamType =
2769 (OMX_PORT_PARAM_TYPE *) paramData;
2770 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2771
2772 portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2773 portParamType->nSize = sizeof(portParamType);
2774 portParamType->nPorts = 2;
2775 portParamType->nStartPortNumber = 0;
2776 break;
2777 }
2778 case OMX_IndexParamVideoPortFormat:
2779 {
2780 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2781 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2782 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
2783
2784 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2785 portFmt->nSize = sizeof(portFmt);
2786
2787 if (0 == portFmt->nPortIndex)
2788 {
2789 if (0 == portFmt->nIndex)
2790 {
2791 portFmt->eColorFormat = OMX_COLOR_FormatUnused;
2792 portFmt->eCompressionFormat = eCompressionFormat;
2793 }
2794 else
2795 {
2796 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2797 " NoMore compression formats\n");
2798 eRet = OMX_ErrorNoMore;
2799 }
2800 }
2801 else if (1 == portFmt->nPortIndex)
2802 {
2803 portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
2804
2805 if(0 == portFmt->nIndex)
Vinay Kaliada4f4422013-01-09 10:45:03 -08002806 portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2807 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
2808 else if (1 == portFmt->nIndex)
2809 portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
Shalaj Jain273b3e02012-06-22 19:08:03 -07002810 else
2811 {
2812 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2813 " NoMore Color formats\n");
2814 eRet = OMX_ErrorNoMore;
2815 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002816 ALOGE("returning %d\n", portFmt->eColorFormat);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002817 }
2818 else
2819 {
2820 DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2821 (int)portFmt->nPortIndex);
2822 eRet = OMX_ErrorBadPortIndex;
2823 }
2824 break;
2825 }
2826 /*Component should support this port definition*/
2827 case OMX_IndexParamAudioInit:
2828 {
2829 OMX_PORT_PARAM_TYPE *audioPortParamType =
2830 (OMX_PORT_PARAM_TYPE *) paramData;
2831 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2832 audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2833 audioPortParamType->nSize = sizeof(audioPortParamType);
2834 audioPortParamType->nPorts = 0;
2835 audioPortParamType->nStartPortNumber = 0;
2836 break;
2837 }
2838 /*Component should support this port definition*/
2839 case OMX_IndexParamImageInit:
2840 {
2841 OMX_PORT_PARAM_TYPE *imagePortParamType =
2842 (OMX_PORT_PARAM_TYPE *) paramData;
2843 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2844 imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2845 imagePortParamType->nSize = sizeof(imagePortParamType);
2846 imagePortParamType->nPorts = 0;
2847 imagePortParamType->nStartPortNumber = 0;
2848 break;
2849
2850 }
2851 /*Component should support this port definition*/
2852 case OMX_IndexParamOtherInit:
2853 {
2854 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2855 paramIndex);
2856 eRet =OMX_ErrorUnsupportedIndex;
2857 break;
2858 }
2859 case OMX_IndexParamStandardComponentRole:
2860 {
2861 OMX_PARAM_COMPONENTROLETYPE *comp_role;
2862 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2863 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2864 comp_role->nSize = sizeof(*comp_role);
2865
2866 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2867 paramIndex);
2868 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2869 OMX_MAX_STRINGNAME_SIZE);
2870 break;
2871 }
2872 /* Added for parameter test */
2873 case OMX_IndexParamPriorityMgmt:
2874 {
2875
2876 OMX_PRIORITYMGMTTYPE *priorityMgmType =
2877 (OMX_PRIORITYMGMTTYPE *) paramData;
2878 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2879 priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2880 priorityMgmType->nSize = sizeof(priorityMgmType);
2881
2882 break;
2883 }
2884 /* Added for parameter test */
2885 case OMX_IndexParamCompBufferSupplier:
2886 {
2887 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2888 (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2889 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2890
2891 bufferSupplierType->nSize = sizeof(bufferSupplierType);
2892 bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2893 if(0 == bufferSupplierType->nPortIndex)
2894 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2895 else if (1 == bufferSupplierType->nPortIndex)
2896 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2897 else
2898 eRet = OMX_ErrorBadPortIndex;
2899
2900
2901 break;
2902 }
2903 case OMX_IndexParamVideoAvc:
2904 {
2905 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2906 paramIndex);
2907 break;
2908 }
2909 case OMX_IndexParamVideoH263:
2910 {
2911 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2912 paramIndex);
2913 break;
2914 }
2915 case OMX_IndexParamVideoMpeg4:
2916 {
2917 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2918 paramIndex);
2919 break;
2920 }
2921 case OMX_IndexParamVideoMpeg2:
2922 {
2923 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2924 paramIndex);
2925 break;
2926 }
2927 case OMX_IndexParamVideoProfileLevelQuerySupported:
2928 {
2929 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2930 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2931 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2932 eRet = get_supported_profile_level_for_1080p(profileLevelType);
2933 break;
2934 }
2935#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2936 case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
2937 {
2938 DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
2939 GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2940 if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
2941
2942 if(secure_mode) {
2943 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
Riaz Rahaman4c3f67e2012-12-26 12:12:25 +05302944 GRALLOC_USAGE_PRIVATE_UNCACHED);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002945 } else {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07002946 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED |
2947 GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
Shalaj Jain273b3e02012-06-22 19:08:03 -07002948 }
2949 } else {
2950 DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
2951 eRet = OMX_ErrorBadParameter;
2952 }
2953 }
2954 break;
2955#endif
2956
2957 default:
2958 {
2959 DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2960 eRet =OMX_ErrorUnsupportedIndex;
2961 }
2962
2963 }
2964
2965 DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
2966 drv_ctx.video_resolution.frame_width,
2967 drv_ctx.video_resolution.frame_height,
2968 drv_ctx.video_resolution.stride,
2969 drv_ctx.video_resolution.scan_lines);
2970
2971 return eRet;
2972}
2973
2974#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2975OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2976{
2977 DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2978 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2979 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2980
2981 if((params == NULL) ||
2982 (params->nativeBuffer == NULL) ||
2983 (params->nativeBuffer->handle == NULL) ||
2984 !m_enable_android_native_buffers)
2985 return OMX_ErrorBadParameter;
2986 m_use_android_native_buffers = OMX_TRUE;
2987 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2988 private_handle_t *handle = (private_handle_t *)nBuf->handle;
2989 if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
2990 OMX_U8 *buffer = NULL;
2991 if(!secure_mode) {
2992 buffer = (OMX_U8*)mmap(0, handle->size,
2993 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
2994 if(buffer == MAP_FAILED) {
2995 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2996 return OMX_ErrorInsufficientResources;
2997 }
2998 }
2999 eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
3000 } else {
3001 eRet = OMX_ErrorBadParameter;
3002 }
3003 return eRet;
3004}
3005#endif
3006/* ======================================================================
3007FUNCTION
3008 omx_vdec::Setparameter
3009
3010DESCRIPTION
3011 OMX Set Parameter method implementation.
3012
3013PARAMETERS
3014 <TBD>.
3015
3016RETURN VALUE
3017 OMX Error None if successful.
3018
3019========================================================================== */
3020OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
3021 OMX_IN OMX_INDEXTYPE paramIndex,
3022 OMX_IN OMX_PTR paramData)
3023{
3024 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3025 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003026 int ret=0;
3027 struct v4l2_format fmt;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003028 if(m_state == OMX_StateInvalid)
3029 {
3030 DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
3031 return OMX_ErrorInvalidState;
3032 }
3033 if(paramData == NULL)
3034 {
3035 DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
3036 return OMX_ErrorBadParameter;
3037 }
3038 if((m_state != OMX_StateLoaded) &&
3039 BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
3040 (m_out_bEnabled == OMX_TRUE) &&
3041 BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
3042 (m_inp_bEnabled == OMX_TRUE)) {
3043 DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
3044 return OMX_ErrorIncorrectStateOperation;
3045 }
3046 switch(paramIndex)
3047 {
3048 case OMX_IndexParamPortDefinition:
3049 {
3050 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
3051 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
3052 //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
3053 //been called.
3054 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
3055 (int)portDefn->format.video.nFrameHeight,
3056 (int)portDefn->format.video.nFrameWidth);
3057 if(OMX_DirOutput == portDefn->eDir)
3058 {
3059 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
3060 m_display_id = portDefn->format.video.pNativeWindow;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003061 unsigned int buffer_size;
3062 if (!client_buffers.get_buffer_req(buffer_size)) {
3063 DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
Shalaj Jain273b3e02012-06-22 19:08:03 -07003064 eRet = OMX_ErrorBadParameter;
Vinay Kaliada4f4422013-01-09 10:45:03 -08003065 } else {
3066 if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
3067 portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size )
3068 {
3069 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
3070 drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
3071 eRet = set_buffer_req(&drv_ctx.op_buf);
3072 if (eRet == OMX_ErrorNone)
3073 m_port_def = *portDefn;
3074 }
3075 else
3076 {
3077 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%d: %u)\n",
3078 drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
3079 portDefn->nBufferCountActual, portDefn->nBufferSize);
3080 eRet = OMX_ErrorBadParameter;
3081 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003082 }
3083 }
3084 else if(OMX_DirInput == portDefn->eDir)
3085 {
3086 if((portDefn->format.video.xFramerate >> 16) > 0 &&
3087 (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS)
3088 {
3089 // Frame rate only should be set if this is a "known value" or to
3090 // activate ts prediction logic (arbitrary mode only) sending input
3091 // timestamps with max value (LLONG_MAX).
3092 DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %d",
3093 portDefn->format.video.xFramerate >> 16);
3094 Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
3095 drv_ctx.frame_rate.fps_denominator);
3096 if(!drv_ctx.frame_rate.fps_numerator)
3097 {
3098 DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
3099 drv_ctx.frame_rate.fps_numerator = 30;
3100 }
3101 if(drv_ctx.frame_rate.fps_denominator)
3102 drv_ctx.frame_rate.fps_numerator = (int)
3103 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
3104 drv_ctx.frame_rate.fps_denominator = 1;
3105 frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
3106 drv_ctx.frame_rate.fps_numerator;
3107 ioctl_msg.in = &drv_ctx.frame_rate;
3108 if (/*ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE,
3109 (void*)&ioctl_msg) < */0)
3110 {
3111 DEBUG_PRINT_ERROR("Setting frame rate to driver failed");
3112 }
3113 DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
3114 frm_int, drv_ctx.frame_rate.fps_numerator /
3115 (float)drv_ctx.frame_rate.fps_denominator);
3116 }
3117 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
3118 if(drv_ctx.video_resolution.frame_height !=
3119 portDefn->format.video.nFrameHeight ||
3120 drv_ctx.video_resolution.frame_width !=
3121 portDefn->format.video.nFrameWidth)
3122 {
3123 DEBUG_PRINT_LOW("\n SetParam IP: WxH(%d x %d)\n",
3124 portDefn->format.video.nFrameWidth,
3125 portDefn->format.video.nFrameHeight);
3126 if (portDefn->format.video.nFrameHeight != 0x0 &&
3127 portDefn->format.video.nFrameWidth != 0x0)
3128 {
Vinay Kalia592e4b42012-12-19 15:55:47 -08003129 update_resolution(portDefn->format.video.nFrameWidth,
3130 portDefn->format.video.nFrameHeight);
Praneeth Paladugu226667c2012-09-12 16:42:30 -07003131 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
3132 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3133 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3134 fmt.fmt.pix_mp.pixelformat = output_capability;
3135 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);
3136 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003137 if (/*ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICRES,
3138 (void*)&ioctl_msg) < */0)
3139 {
3140 DEBUG_PRINT_ERROR("\n Set Resolution failed");
3141 eRet = OMX_ErrorUnsupportedSetting;
3142 }
3143 else
3144 eRet = get_buffer_req(&drv_ctx.op_buf);
3145 }
3146 }
3147 else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003148 || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07003149 {
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003150 vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003151 drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
Deva Ramasubramanian66433c12012-11-20 18:29:34 -08003152 drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
3153 (~(buffer_prop->alignment - 1));
3154 eRet = set_buffer_req(buffer_prop);
Shalaj Jain273b3e02012-06-22 19:08:03 -07003155 }
3156 else
3157 {
3158 DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%d: %u)\n",
3159 drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3160 portDefn->nBufferCountActual, portDefn->nBufferSize);
3161 eRet = OMX_ErrorBadParameter;
3162 }
3163 }
3164 else if (portDefn->eDir == OMX_DirMax)
3165 {
3166 DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3167 (int)portDefn->nPortIndex);
3168 eRet = OMX_ErrorBadPortIndex;
3169 }
3170 }
3171 break;
3172 case OMX_IndexParamVideoPortFormat:
3173 {
3174 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3175 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3176 int ret=0;
3177 struct v4l2_format fmt;
3178 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
3179 portFmt->eColorFormat);
3180
3181 if(1 == portFmt->nPortIndex)
3182 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08003183 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3184 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
3185 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
3186 fmt.fmt.pix_mp.pixelformat = capture_capability;
3187 enum vdec_output_fromat op_format;
3188 if((portFmt->eColorFormat == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
3189 (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
3190 op_format = VDEC_YUV_FORMAT_NV12;
3191 else if(portFmt->eColorFormat ==
3192 QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
3193 op_format = VDEC_YUV_FORMAT_TILE_4x2;
3194 else
3195 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003196
Vinay Kaliada4f4422013-01-09 10:45:03 -08003197 if(eRet == OMX_ErrorNone)
3198 {
3199 drv_ctx.output_format = op_format;
3200 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
3201 if(ret)
3202 {
3203 DEBUG_PRINT_ERROR("\n Set output format failed");
3204 eRet = OMX_ErrorUnsupportedSetting;
3205 /*TODO: How to handle this case */
3206 }
3207 else
3208 {
3209 eRet = get_buffer_req(&drv_ctx.op_buf);
3210 }
3211 }
3212 if (eRet == OMX_ErrorNone){
3213 if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3214 DEBUG_PRINT_ERROR("\n Set color format failed");
3215 eRet = OMX_ErrorBadParameter;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003216 }
Vinay Kaliada4f4422013-01-09 10:45:03 -08003217 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003218 }
3219 }
3220 break;
3221
3222 case OMX_QcomIndexPortDefn:
3223 {
3224 OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3225 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
3226 DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d\n",
3227 portFmt->nFramePackingFormat);
3228
3229 /* Input port */
3230 if (portFmt->nPortIndex == 0)
3231 {
3232 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
3233 {
3234 if(secure_mode) {
3235 arbitrary_bytes = false;
3236 DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3237 eRet = OMX_ErrorUnsupportedSetting;
3238 } else {
3239 arbitrary_bytes = true;
3240 }
3241 }
3242 else if (portFmt->nFramePackingFormat ==
3243 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
3244 {
3245 arbitrary_bytes = false;
3246 }
3247 else
3248 {
3249 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %d\n",
3250 portFmt->nFramePackingFormat);
3251 eRet = OMX_ErrorUnsupportedSetting;
3252 }
3253 }
3254 else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX)
3255 {
3256 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
3257 if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3258 portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3259 portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone)
3260 {
3261 m_out_mem_region_smi = OMX_TRUE;
3262 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3263 {
3264 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
3265 m_use_output_pmem = OMX_TRUE;
3266 }
3267 }
3268 }
3269 }
3270 break;
3271
3272 case OMX_IndexParamStandardComponentRole:
3273 {
3274 OMX_PARAM_COMPONENTROLETYPE *comp_role;
3275 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3276 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
3277 comp_role->cRole);
3278
3279 if((m_state == OMX_StateLoaded)&&
3280 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3281 {
3282 DEBUG_PRINT_LOW("Set Parameter called in valid state");
3283 }
3284 else
3285 {
3286 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3287 return OMX_ErrorIncorrectStateOperation;
3288 }
3289
3290 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3291 {
3292 if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3293 {
3294 strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3295 }
3296 else
3297 {
3298 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3299 eRet =OMX_ErrorUnsupportedSetting;
3300 }
3301 }
3302 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3303 {
3304 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3305 {
3306 strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3307 }
3308 else
3309 {
3310 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3311 eRet = OMX_ErrorUnsupportedSetting;
3312 }
3313 }
3314 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3315 {
3316 if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3317 {
3318 strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3319 }
3320 else
3321 {
3322 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3323 eRet =OMX_ErrorUnsupportedSetting;
3324 }
3325 }
3326 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3327 {
3328 if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
3329 {
3330 strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3331 }
3332 else
3333 {
3334 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3335 eRet = OMX_ErrorUnsupportedSetting;
3336 }
3337 }
3338 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3339 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3340 )
3341 {
3342 if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3343 {
3344 strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3345 }
3346 else
3347 {
3348 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3349 eRet =OMX_ErrorUnsupportedSetting;
3350 }
3351 }
3352 else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3353 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3354 )
3355 {
3356 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3357 {
3358 strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3359 }
3360 else
3361 {
3362 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3363 eRet =OMX_ErrorUnsupportedSetting;
3364 }
3365 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003366 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
3367 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003368 if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
3369 (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE)))
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07003370 {
3371 strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
3372 }
3373 else
3374 {
3375 DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3376 eRet = OMX_ErrorUnsupportedSetting;
3377 }
3378 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003379 else
3380 {
3381 DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3382 eRet = OMX_ErrorInvalidComponentName;
3383 }
3384 break;
3385 }
3386
3387 case OMX_IndexParamPriorityMgmt:
3388 {
3389 if(m_state != OMX_StateLoaded)
3390 {
3391 DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3392 return OMX_ErrorIncorrectStateOperation;
3393 }
3394 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
3395 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n",
3396 priorityMgmtype->nGroupID);
3397
3398 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n",
3399 priorityMgmtype->nGroupPriority);
3400
3401 m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3402 m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3403
3404 break;
3405 }
3406
3407 case OMX_IndexParamCompBufferSupplier:
3408 {
3409 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3410 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3411 bufferSupplierType->eBufferSupplier);
3412 if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3413 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3414
3415 else
3416
3417 eRet = OMX_ErrorBadPortIndex;
3418
3419 break;
3420
3421 }
3422 case OMX_IndexParamVideoAvc:
3423 {
3424 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3425 paramIndex);
3426 break;
3427 }
3428 case OMX_IndexParamVideoH263:
3429 {
3430 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3431 paramIndex);
3432 break;
3433 }
3434 case OMX_IndexParamVideoMpeg4:
3435 {
3436 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3437 paramIndex);
3438 break;
3439 }
3440 case OMX_IndexParamVideoMpeg2:
3441 {
3442 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3443 paramIndex);
3444 break;
3445 }
3446 case OMX_QcomIndexParamVideoDecoderPictureOrder:
3447 {
3448 QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3449 (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003450 struct v4l2_control control;
3451 int pic_order,rc=0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003452 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3453 pictureOrder->eOutputPictureOrder);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003454 if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
3455 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
3456 }
3457 else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){
3458 pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003459 time_stamp_dts.set_timestamp_reorder_mode(false);
Praneeth Paladugu15c96d82012-07-10 07:06:08 -07003460 }
3461 else
3462 eRet = OMX_ErrorBadParameter;
3463 if (eRet == OMX_ErrorNone)
3464 {
3465 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3466 control.value = pic_order;
3467 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3468 if(rc)
3469 {
3470 DEBUG_PRINT_ERROR("\n Set picture order failed");
3471 eRet = OMX_ErrorUnsupportedSetting;
3472 }
3473 }
3474 break;
3475 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003476 case OMX_QcomIndexParamConcealMBMapExtraData:
3477 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003478 eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003479 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3480 else {
3481 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3482 eRet = OMX_ErrorUnsupportedSetting;
3483 }
3484 break;
3485 case OMX_QcomIndexParamFrameInfoExtraData:
3486 {
3487 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003488 eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003489 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3490 else {
3491 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3492 eRet = OMX_ErrorUnsupportedSetting;
3493 }
3494 break;
3495 }
3496 case OMX_QcomIndexParamInterlaceExtraData:
3497 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003498 eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003499 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3500 else {
3501 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3502 eRet = OMX_ErrorUnsupportedSetting;
3503 }
3504 break;
3505 case OMX_QcomIndexParamH264TimeInfo:
3506 if(!secure_mode)
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003507 eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
Shalaj Jain273b3e02012-06-22 19:08:03 -07003508 ((QOMX_ENABLETYPE *)paramData)->bEnable);
3509 else {
3510 DEBUG_PRINT_ERROR("\n secure mode setting not supported");
3511 eRet = OMX_ErrorUnsupportedSetting;
3512 }
3513 break;
3514 case OMX_QcomIndexParamVideoDivx:
3515 {
3516 QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003517 }
3518 break;
3519 case OMX_QcomIndexPlatformPvt:
3520 {
3521 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
3522 OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3523 if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM)
3524 {
3525 DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3526 eRet = OMX_ErrorUnsupportedSetting;
3527 }
3528 else
3529 {
3530 m_out_pvt_entry_pmem = OMX_TRUE;
3531 if ((m_out_mem_region_smi && m_out_pvt_entry_pmem))
3532 {
3533 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
3534 m_use_output_pmem = OMX_TRUE;
3535 }
3536 }
3537
3538 }
3539 break;
3540 case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3541 {
Praneeth Paladugue3337f62012-10-16 17:35:59 -07003542 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3543 DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3544 struct v4l2_control control;
3545 int rc;
3546 drv_ctx.idr_only_decoding = 1;
3547 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
3548 control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
3549 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3550 if(rc)
3551 {
3552 DEBUG_PRINT_ERROR("\n Set picture order failed");
3553 eRet = OMX_ErrorUnsupportedSetting;
3554 } else {
3555 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
3556 control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
3557 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
3558 if(rc)
3559 {
3560 DEBUG_PRINT_ERROR("\n Sync frame setting failed");
3561 eRet = OMX_ErrorUnsupportedSetting;
3562 }
3563 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003564 }
3565 break;
3566
3567 case OMX_QcomIndexParamIndexExtraDataType:
3568 {
3569 if(!secure_mode) {
3570 QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3571 if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3572 (extradataIndexType->bEnabled == OMX_TRUE) &&
3573 (extradataIndexType->nPortIndex == 1))
3574 {
3575 DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
Vinay Kalia9c00cae2012-12-06 16:08:20 -08003576 eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07003577
Shalaj Jain273b3e02012-06-22 19:08:03 -07003578 }
3579 }
3580 }
3581 break;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07003582 case OMX_QcomIndexParamEnableSmoothStreaming:
3583 {
3584 struct v4l2_control control;
3585 struct v4l2_format fmt;
3586 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
3587 control.value = 1;
3588 int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
3589 if(rc < 0) {
3590 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3591 eRet = OMX_ErrorHardware;
3592 }
3593 }
3594 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07003595#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3596 /* Need to allow following two set_parameters even in Idle
3597 * state. This is ANDROID architecture which is not in sync
3598 * with openmax standard. */
3599 case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3600 {
3601 EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3602 if(enableNativeBuffers) {
3603 m_enable_android_native_buffers = enableNativeBuffers->enable;
3604 }
3605 }
3606 break;
3607 case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3608 {
3609 eRet = use_android_native_buffer(hComp, paramData);
3610 }
3611 break;
3612#endif
3613 case OMX_QcomIndexParamEnableTimeStampReorder:
3614 {
3615 QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3616 if (drv_ctx.picture_order == QOMX_VIDEO_DISPLAY_ORDER) {
3617 if (reorder->bEnable == OMX_TRUE) {
3618 frm_int =0;
3619 time_stamp_dts.set_timestamp_reorder_mode(true);
3620 }
3621 else
3622 time_stamp_dts.set_timestamp_reorder_mode(false);
3623 } else {
3624 time_stamp_dts.set_timestamp_reorder_mode(false);
3625 if (reorder->bEnable == OMX_TRUE)
3626 {
3627 eRet = OMX_ErrorUnsupportedSetting;
3628 }
3629 }
3630 }
3631 break;
3632 default:
3633 {
3634 DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3635 eRet = OMX_ErrorUnsupportedIndex;
3636 }
3637 }
3638 return eRet;
3639}
3640
3641/* ======================================================================
3642FUNCTION
3643 omx_vdec::GetConfig
3644
3645DESCRIPTION
3646 OMX Get Config Method implementation.
3647
3648PARAMETERS
3649 <TBD>.
3650
3651RETURN VALUE
3652 OMX Error None if successful.
3653
3654========================================================================== */
3655OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp,
3656 OMX_IN OMX_INDEXTYPE configIndex,
3657 OMX_INOUT OMX_PTR configData)
3658{
3659 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3660
3661 if (m_state == OMX_StateInvalid)
3662 {
3663 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3664 return OMX_ErrorInvalidState;
3665 }
3666
3667 switch (configIndex)
3668 {
3669 case OMX_QcomIndexConfigInterlaced:
3670 {
3671 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3672 (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3673 if (configFmt->nPortIndex == 1)
3674 {
3675 if (configFmt->nIndex == 0)
3676 {
3677 configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3678 }
3679 else if (configFmt->nIndex == 1)
3680 {
3681 configFmt->eInterlaceType =
3682 OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3683 }
3684 else if (configFmt->nIndex == 2)
3685 {
3686 configFmt->eInterlaceType =
3687 OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3688 }
3689 else
3690 {
3691 DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3692 " NoMore Interlaced formats\n");
3693 eRet = OMX_ErrorNoMore;
3694 }
3695
3696 }
3697 else
3698 {
3699 DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3700 (int)configFmt->nPortIndex);
3701 eRet = OMX_ErrorBadPortIndex;
3702 }
3703 break;
3704 }
3705 case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3706 {
3707 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
3708 QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3709 (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3710 //ioctl_msg.out = (void*)&decoderinstances->nNumOfInstances;
3711 //(void)(ioctl(drv_ctx.video_driver_fd,
3712 //VDEC_IOCTL_GET_NUMBER_INSTANCES,&ioctl_msg));
3713
3714 decoderinstances->nNumOfInstances = 16;
3715 /*TODO: How to handle this case */
3716 break;
3717 }
3718 case OMX_QcomIndexConfigVideoFramePackingArrangement:
3719 {
3720 if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264)
3721 {
3722 OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3723 (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3724 h264_parser->get_frame_pack_data(configFmt);
3725 }
3726 else
3727 {
3728 DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3729 }
3730 break;
3731 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08003732 case OMX_IndexConfigCommonOutputCrop:
3733 {
3734 OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
3735 memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
3736 break;
3737 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07003738 default:
3739 {
3740 DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3741 eRet = OMX_ErrorBadParameter;
3742 }
3743
3744 }
3745
3746 return eRet;
3747}
3748
3749/* ======================================================================
3750FUNCTION
3751 omx_vdec::SetConfig
3752
3753DESCRIPTION
3754 OMX Set Config method implementation
3755
3756PARAMETERS
3757 <TBD>.
3758
3759RETURN VALUE
3760 OMX Error None if successful.
3761========================================================================== */
3762OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp,
3763 OMX_IN OMX_INDEXTYPE configIndex,
3764 OMX_IN OMX_PTR configData)
3765{
3766 if(m_state == OMX_StateInvalid)
3767 {
3768 DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3769 return OMX_ErrorInvalidState;
3770 }
3771
3772 OMX_ERRORTYPE ret = OMX_ErrorNone;
3773 OMX_VIDEO_CONFIG_NALSIZE *pNal;
3774
3775 DEBUG_PRINT_LOW("\n Set Config Called");
3776
3777 if (m_state == OMX_StateExecuting)
3778 {
3779 DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
3780 return ret;
3781 }
3782
3783 if (configIndex == OMX_IndexVendorVideoExtraData)
3784 {
3785 OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3786 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
3787 if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc"))
3788 {
3789 DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
3790 OMX_U32 extra_size;
3791 // Parsing done here for the AVC atom is definitely not generic
3792 // Currently this piece of code is working, but certainly
3793 // not tested with all .mp4 files.
3794 // Incase of failure, we might need to revisit this
3795 // for a generic piece of code.
3796
3797 // Retrieve size of NAL length field
3798 // byte #4 contains the size of NAL lenght field
3799 nal_length = (config->pData[4] & 0x03) + 1;
3800
3801 extra_size = 0;
3802 if (nal_length > 2)
3803 {
3804 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3805 extra_size = (nal_length - 2) * 2;
3806 }
3807
3808 // SPS starts from byte #6
3809 OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3810 OMX_U8 *pDestBuf;
3811 m_vendor_config.nPortIndex = config->nPortIndex;
3812
3813 // minus 6 --> SPS starts from byte #6
3814 // minus 1 --> picture param set byte to be ignored from avcatom
3815 m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3816 m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3817 OMX_U32 len;
3818 OMX_U8 index = 0;
3819 // case where SPS+PPS is sent as part of set_config
3820 pDestBuf = m_vendor_config.pData;
3821
3822 DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]\n",
3823 m_vendor_config.nPortIndex,
3824 m_vendor_config.nDataSize,
3825 m_vendor_config.pData);
3826 while (index < 2)
3827 {
3828 uint8 *psize;
3829 len = *pSrcBuf;
3830 len = len << 8;
3831 len |= *(pSrcBuf + 1);
3832 psize = (uint8 *) & len;
3833 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3834 for (int i = 0; i < nal_length; i++)
3835 {
3836 pDestBuf[i] = psize[nal_length - 1 - i];
3837 }
3838 //memcpy(pDestBuf,pSrcBuf,(len+2));
3839 pDestBuf += len + nal_length;
3840 pSrcBuf += len + 2;
3841 index++;
3842 pSrcBuf++; // skip picture param set
3843 len = 0;
3844 }
3845 }
3846 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3847 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2"))
3848 {
3849 m_vendor_config.nPortIndex = config->nPortIndex;
3850 m_vendor_config.nDataSize = config->nDataSize;
3851 m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3852 memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3853 }
3854 else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1"))
3855 {
3856 if(m_vendor_config.pData)
3857 {
3858 free(m_vendor_config.pData);
3859 m_vendor_config.pData = NULL;
3860 m_vendor_config.nDataSize = 0;
3861 }
3862
3863 if (((*((OMX_U32 *) config->pData)) &
3864 VC1_SP_MP_START_CODE_MASK) ==
3865 VC1_SP_MP_START_CODE)
3866 {
3867 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3868 m_vendor_config.nPortIndex = config->nPortIndex;
3869 m_vendor_config.nDataSize = config->nDataSize;
3870 m_vendor_config.pData =
3871 (OMX_U8 *) malloc(config->nDataSize);
3872 memcpy(m_vendor_config.pData, config->pData,
3873 config->nDataSize);
3874 m_vc1_profile = VC1_SP_MP_RCV;
3875 }
3876 else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
3877 {
3878 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3879 m_vendor_config.nPortIndex = config->nPortIndex;
3880 m_vendor_config.nDataSize = config->nDataSize;
3881 m_vendor_config.pData =
3882 (OMX_U8 *) malloc((config->nDataSize));
3883 memcpy(m_vendor_config.pData, config->pData,
3884 config->nDataSize);
3885 m_vc1_profile = VC1_AP;
3886 }
3887 else if ((config->nDataSize == VC1_STRUCT_C_LEN))
3888 {
3889 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3890 m_vendor_config.nPortIndex = config->nPortIndex;
3891 m_vendor_config.nDataSize = config->nDataSize;
3892 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3893 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3894 m_vc1_profile = VC1_SP_MP_RCV;
3895 }
3896 else
3897 {
3898 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3899 }
3900 }
3901 return ret;
3902 }
3903 else if (configIndex == OMX_IndexConfigVideoNalSize)
3904 {
3905
3906 pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3907 nal_length = pNal->nNaluBytes;
3908 m_frame_parser.init_nal_length(nal_length);
3909 DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length);
3910 return ret;
3911 }
3912
3913 return OMX_ErrorNotImplemented;
3914}
3915
3916/* ======================================================================
3917FUNCTION
3918 omx_vdec::GetExtensionIndex
3919
3920DESCRIPTION
3921 OMX GetExtensionIndex method implementaion. <TBD>
3922
3923PARAMETERS
3924 <TBD>.
3925
3926RETURN VALUE
3927 OMX Error None if everything successful.
3928
3929========================================================================== */
3930OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
3931 OMX_IN OMX_STRING paramName,
3932 OMX_OUT OMX_INDEXTYPE* indexType)
3933{
3934 if(m_state == OMX_StateInvalid)
3935 {
3936 DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3937 return OMX_ErrorInvalidState;
3938 }
3939 else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3940 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3941 }
3942 else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1))
3943 {
3944 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3945 }
3946#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3947 else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
3948 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
3949 }
3950 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
3951 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
3952 }
3953 else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
3954 DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3955 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
3956 }
3957 else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
3958 *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3959 }
3960#endif
3961 else {
3962 DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3963 return OMX_ErrorNotImplemented;
3964 }
3965 return OMX_ErrorNone;
3966}
3967
3968/* ======================================================================
3969FUNCTION
3970 omx_vdec::GetState
3971
3972DESCRIPTION
3973 Returns the state information back to the caller.<TBD>
3974
3975PARAMETERS
3976 <TBD>.
3977
3978RETURN VALUE
3979 Error None if everything is successful.
3980========================================================================== */
3981OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
3982 OMX_OUT OMX_STATETYPE* state)
3983{
3984 *state = m_state;
3985 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
3986 return OMX_ErrorNone;
3987}
3988
3989/* ======================================================================
3990FUNCTION
3991 omx_vdec::ComponentTunnelRequest
3992
3993DESCRIPTION
3994 OMX Component Tunnel Request method implementation. <TBD>
3995
3996PARAMETERS
3997 None.
3998
3999RETURN VALUE
4000 OMX Error None if everything successful.
4001
4002========================================================================== */
4003OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
4004 OMX_IN OMX_U32 port,
4005 OMX_IN OMX_HANDLETYPE peerComponent,
4006 OMX_IN OMX_U32 peerPort,
4007 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
4008{
4009 DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
4010 return OMX_ErrorNotImplemented;
4011}
4012
4013/* ======================================================================
4014FUNCTION
4015 omx_vdec::UseOutputBuffer
4016
4017DESCRIPTION
4018 Helper function for Use buffer in the input pin
4019
4020PARAMETERS
4021 None.
4022
4023RETURN VALUE
4024 true/false
4025
4026========================================================================== */
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004027OMX_ERRORTYPE omx_vdec::allocate_extradata()
4028{
4029#ifdef USE_ION
4030 if (drv_ctx.extradata_info.buffer_size) {
4031 if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
4032 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4033 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4034 free_ion_memory(&drv_ctx.extradata_info.ion);
4035 }
4036 drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
4037 drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
4038 drv_ctx.extradata_info.count * drv_ctx.extradata_info.size, 4096,
4039 &drv_ctx.extradata_info.ion.ion_alloc_data,
4040 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
4041 if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
4042 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
4043 return OMX_ErrorInsufficientResources;
4044 }
4045 drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
4046 drv_ctx.extradata_info.size,
4047 PROT_READ|PROT_WRITE, MAP_SHARED,
4048 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
4049 if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
4050 DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
4051 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4052 free_ion_memory(&drv_ctx.extradata_info.ion);
4053 return OMX_ErrorInsufficientResources;
4054 }
4055 }
4056#endif
4057 return OMX_ErrorNone;
4058}
4059
4060void omx_vdec::free_extradata() {
4061#ifdef USE_ION
4062 if (drv_ctx.extradata_info.uaddr) {
4063 munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
4064 close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
4065 free_ion_memory(&drv_ctx.extradata_info.ion);
4066 }
4067 memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
4068#endif
4069}
4070
Shalaj Jain273b3e02012-06-22 19:08:03 -07004071OMX_ERRORTYPE omx_vdec::use_output_buffer(
4072 OMX_IN OMX_HANDLETYPE hComp,
4073 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4074 OMX_IN OMX_U32 port,
4075 OMX_IN OMX_PTR appData,
4076 OMX_IN OMX_U32 bytes,
4077 OMX_IN OMX_U8* buffer)
4078{
4079 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4080 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4081 unsigned i= 0; // Temporary counter
4082 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4083 struct vdec_setbuffer_cmd setbuffers;
4084 OMX_PTR privateAppData = NULL;
4085 private_handle_t *handle = NULL;
4086 OMX_U8 *buff = buffer;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004087 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004088 struct v4l2_plane plane[VIDEO_MAX_PLANES];
4089 int extra_idx = 0;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004090
Shalaj Jain273b3e02012-06-22 19:08:03 -07004091 if (!m_out_mem_ptr) {
4092 DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
4093 eRet = allocate_output_headers();
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004094 if (eRet == OMX_ErrorNone)
4095 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07004096 }
4097
4098 if (eRet == OMX_ErrorNone) {
4099 for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
4100 if(BITMASK_ABSENT(&m_out_bm_count,i))
4101 {
4102 break;
4103 }
4104 }
4105 }
4106
4107 if(i >= drv_ctx.op_buf.actualcount) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004108 DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004109 eRet = OMX_ErrorInsufficientResources;
4110 }
4111
4112 if (eRet == OMX_ErrorNone) {
4113#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
4114 if(m_enable_android_native_buffers) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004115 if (m_use_android_native_buffers) {
4116 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
4117 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
4118 handle = (private_handle_t *)nBuf->handle;
4119 privateAppData = params->pAppPrivate;
4120 } else {
4121 handle = (private_handle_t *)buff;
4122 privateAppData = appData;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004123 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004124
4125 if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
4126 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
4127 " expected %u, got %lu",
4128 drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
4129 return OMX_ErrorBadParameter;
4130 }
4131
4132 if (!m_use_android_native_buffers) {
4133 if (!secure_mode) {
4134 buff = (OMX_U8*)mmap(0, handle->size,
4135 PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
4136 if (buff == MAP_FAILED) {
4137 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
4138 return OMX_ErrorInsufficientResources;
4139 }
4140 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004141 }
4142#if defined(_ANDROID_ICS_)
4143 native_buffer[i].nativehandle = handle;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004144 native_buffer[i].privatehandle = handle;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004145#endif
4146 if(!handle) {
4147 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
4148 return OMX_ErrorBadParameter;
4149 }
4150 drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
4151 drv_ctx.ptr_outputbuffer[i].offset = 0;
4152 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4153 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4154 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4155 } else
4156#endif
4157
4158 if (!ouput_egl_buffers && !m_use_output_pmem) {
4159#ifdef USE_ION
4160 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4161 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4162 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004163 &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004164 if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004165 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 -07004166 return OMX_ErrorInsufficientResources;
4167 }
4168 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4169 drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4170#else
4171 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4172 open (MEM_DEVICE,O_RDWR);
4173
4174 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004175 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 -07004176 return OMX_ErrorInsufficientResources;
4177 }
4178
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004179 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
Shalaj Jain273b3e02012-06-22 19:08:03 -07004180 if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0)
4181 {
4182 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
4183 open (MEM_DEVICE,O_RDWR);
4184 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004185 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 -07004186 return OMX_ErrorInsufficientResources;
4187 }
4188 }
4189
4190 if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4191 drv_ctx.op_buf.buffer_size,
4192 drv_ctx.op_buf.alignment))
4193 {
4194 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4195 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4196 return OMX_ErrorInsufficientResources;
4197 }
4198#endif
4199 if(!secure_mode) {
4200 drv_ctx.ptr_outputbuffer[i].bufferaddr =
4201 (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4202 PROT_READ|PROT_WRITE, MAP_SHARED,
4203 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4204 if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4205 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4206#ifdef USE_ION
4207 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4208#endif
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004209 DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004210 return OMX_ErrorInsufficientResources;
4211 }
4212 }
4213 drv_ctx.ptr_outputbuffer[i].offset = 0;
4214 privateAppData = appData;
4215 }
4216 else {
4217
4218 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4219 if (!appData || !bytes ) {
4220 if(!secure_mode && !buffer) {
4221 DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4222 return OMX_ErrorBadParameter;
4223 }
4224 }
4225
4226 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4227 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4228 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4229 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4230 !pmem_list->nEntries ||
4231 pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4232 DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4233 return OMX_ErrorBadParameter;
4234 }
4235 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4236 pmem_list->entryList->entry;
4237 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x",
4238 pmem_info->pmem_fd);
4239 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4240 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4241 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4242 drv_ctx.ptr_outputbuffer[i].mmaped_size =
4243 drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4244 privateAppData = appData;
4245 }
4246 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4247 m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4248
4249 *bufferHdr = (m_out_mem_ptr + i );
4250 if(secure_mode)
4251 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4252 //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4253 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4254 sizeof (vdec_bufferpayload));
4255
4256 // ioctl_msg.in = &setbuffers;
4257 // ioctl_msg.out = NULL;
4258
4259 DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %x, pmem_fd=%0x%x", i,
4260 drv_ctx.ptr_outputbuffer[i],drv_ctx.ptr_outputbuffer[i].pmem_fd );
4261 // if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
4262 // &ioctl_msg) < 0)
4263 // {
4264 // DEBUG_PRINT_ERROR("\n Set output buffer failed");
4265 // return OMX_ErrorInsufficientResources;
4266 // }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004267
4268
4269
4270 buf.index = i;
4271 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4272 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004273 plane[0].length = drv_ctx.op_buf.buffer_size;
4274 plane[0].m.userptr = (unsigned long)(drv_ctx.ptr_outputbuffer[i].bufferaddr-drv_ctx.ptr_outputbuffer[i].offset);
4275 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4276 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
4277 plane[0].data_offset = 0;
4278 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
4279 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
4280 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
4281 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
4282#ifdef USE_ION
4283 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
4284#endif
4285 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
4286 plane[extra_idx].data_offset = 0;
4287 } else if (extra_idx >= VIDEO_MAX_PLANES) {
4288 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
4289 return OMX_ErrorBadParameter;
4290 }
4291 buf.m.planes = plane;
4292 buf.length = drv_ctx.num_planes;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004293
4294 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]);
4295
4296 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
4297 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
4298 /*TODO: How to handle this case */
4299 return OMX_ErrorInsufficientResources;
4300 }
4301
4302 if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
4303 enum v4l2_buf_type buf_type;
4304 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
4305 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
4306 return OMX_ErrorInsufficientResources;
4307 } else {
4308 streaming[CAPTURE_PORT] = true;
4309 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
4310 }
4311 }
4312
Shalaj Jain273b3e02012-06-22 19:08:03 -07004313 (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004314 if (m_enable_android_native_buffers) {
4315 DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4316 (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4317 } else {
4318 (*bufferHdr)->pBuffer = buff;
4319 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004320 (*bufferHdr)->pAppPrivate = privateAppData;
4321 BITMASK_SET(&m_out_bm_count,i);
4322 }
4323 return eRet;
4324}
4325
4326/* ======================================================================
4327FUNCTION
4328 omx_vdec::use_input_heap_buffers
4329
4330DESCRIPTION
4331 OMX Use Buffer Heap allocation method implementation.
4332
4333PARAMETERS
4334 <TBD>.
4335
4336RETURN VALUE
4337 OMX Error None , if everything successful.
4338
4339========================================================================== */
4340OMX_ERRORTYPE omx_vdec::use_input_heap_buffers(
4341 OMX_IN OMX_HANDLETYPE hComp,
4342 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4343 OMX_IN OMX_U32 port,
4344 OMX_IN OMX_PTR appData,
4345 OMX_IN OMX_U32 bytes,
4346 OMX_IN OMX_U8* buffer)
4347{
4348 DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
4349 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4350 if(!m_inp_heap_ptr)
4351 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4352 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4353 drv_ctx.ip_buf.actualcount);
4354 if(!m_phdr_pmem_ptr)
4355 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4356 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4357 drv_ctx.ip_buf.actualcount);
4358 if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
4359 {
4360 DEBUG_PRINT_ERROR("Insufficent memory");
4361 eRet = OMX_ErrorInsufficientResources;
4362 }
4363 else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
4364 {
4365 input_use_buffer = true;
4366 memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4367 m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4368 m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4369 m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4370 m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4371 m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4372 *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4373 eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4374 DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
4375 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], NULL, NULL))
4376 {
4377 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4378 return OMX_ErrorInsufficientResources;
4379 }
4380 m_in_alloc_cnt++;
4381 }
4382 else
4383 {
4384 DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4385 eRet = OMX_ErrorInsufficientResources;
4386 }
4387 return eRet;
4388}
4389
4390/* ======================================================================
4391FUNCTION
4392 omx_vdec::UseBuffer
4393
4394DESCRIPTION
4395 OMX Use Buffer method implementation.
4396
4397PARAMETERS
4398 <TBD>.
4399
4400RETURN VALUE
4401 OMX Error None , if everything successful.
4402
4403========================================================================== */
4404OMX_ERRORTYPE omx_vdec::use_buffer(
4405 OMX_IN OMX_HANDLETYPE hComp,
4406 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4407 OMX_IN OMX_U32 port,
4408 OMX_IN OMX_PTR appData,
4409 OMX_IN OMX_U32 bytes,
4410 OMX_IN OMX_U8* buffer)
4411{
4412 OMX_ERRORTYPE error = OMX_ErrorNone;
4413 struct vdec_setbuffer_cmd setbuffers;
4414 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4415
4416 if (bufferHdr == NULL || bytes == 0)
4417 {
4418 if(!secure_mode && buffer == NULL) {
4419 DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
4420 return OMX_ErrorBadParameter;
4421 }
4422 }
4423 if(m_state == OMX_StateInvalid)
4424 {
4425 DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4426 return OMX_ErrorInvalidState;
4427 }
4428 if(port == OMX_CORE_INPUT_PORT_INDEX)
4429 error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4430 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
4431 error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4432 else
4433 {
4434 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4435 error = OMX_ErrorBadPortIndex;
4436 }
4437 DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error);
4438 if(error == OMX_ErrorNone)
4439 {
4440 if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
4441 {
4442 // Send the callback now
4443 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4444 post_event(OMX_CommandStateSet,OMX_StateIdle,
4445 OMX_COMPONENT_GENERATE_EVENT);
4446 }
4447 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4448 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
4449 {
4450 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4451 post_event(OMX_CommandPortEnable,
4452 OMX_CORE_INPUT_PORT_INDEX,
4453 OMX_COMPONENT_GENERATE_EVENT);
4454 }
4455 else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4456 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
4457 {
4458 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4459 post_event(OMX_CommandPortEnable,
4460 OMX_CORE_OUTPUT_PORT_INDEX,
4461 OMX_COMPONENT_GENERATE_EVENT);
4462 }
4463 }
4464 return error;
4465}
4466
4467OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4468 OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4469{
4470 if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes)
4471 {
4472 if(m_inp_heap_ptr[bufferindex].pBuffer)
4473 free(m_inp_heap_ptr[bufferindex].pBuffer);
4474 m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4475 }
4476 if (pmem_bufferHdr)
4477 free_input_buffer(pmem_bufferHdr);
4478 return OMX_ErrorNone;
4479}
4480
4481OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4482{
4483 unsigned int index = 0;
4484 if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
4485 {
4486 return OMX_ErrorBadParameter;
4487 }
4488
4489 index = bufferHdr - m_inp_mem_ptr;
4490 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4491
4492 if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer)
4493 {
4494 DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
4495 if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0)
4496 {
4497 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4498 struct vdec_setbuffer_cmd setbuffers;
4499 setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4500 memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4501 sizeof (vdec_bufferpayload));
4502 ioctl_msg.in = &setbuffers;
4503 ioctl_msg.out = NULL;
4504 int ioctl_r; //= ioctl (drv_ctx.video_driver_fd,
4505 // VDEC_IOCTL_FREE_BUFFER, &ioctl_msg);
4506 if (ioctl_r < 0)
4507 {
4508 DEBUG_PRINT_ERROR("\nVDEC_IOCTL_FREE_BUFFER returned error %d", ioctl_r);
4509 }
4510
4511 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
4512 drv_ctx.ptr_inputbuffer[index].pmem_fd);
4513 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %d",
4514 drv_ctx.ptr_inputbuffer[index].mmaped_size,
4515 drv_ctx.ptr_inputbuffer[index].bufferaddr);
4516 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4517 drv_ctx.ptr_inputbuffer[index].mmaped_size);
4518 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4519 drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4520 if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr)
4521 {
4522 free(m_desc_buffer_ptr[index].buf_addr);
4523 m_desc_buffer_ptr[index].buf_addr = NULL;
4524 m_desc_buffer_ptr[index].desc_data_size = 0;
4525 }
4526#ifdef USE_ION
4527 free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4528#endif
4529 }
4530 }
4531
4532 return OMX_ErrorNone;
4533}
4534
4535OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4536{
4537 unsigned int index = 0;
4538
4539 if (bufferHdr == NULL || m_out_mem_ptr == NULL)
4540 {
4541 return OMX_ErrorBadParameter;
4542 }
4543
4544 index = bufferHdr - m_out_mem_ptr;
4545 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
4546
4547 if (index < drv_ctx.op_buf.actualcount
4548 && drv_ctx.ptr_outputbuffer)
4549 {
4550 DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index,
4551 drv_ctx.ptr_outputbuffer[index].bufferaddr);
4552
4553 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4554 struct vdec_setbuffer_cmd setbuffers;
4555 setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4556 memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4557 sizeof (vdec_bufferpayload));
4558 ioctl_msg.in = &setbuffers;
4559 ioctl_msg.out = NULL;
4560 DEBUG_PRINT_LOW("\nRelease the Output Buffer");
4561 if (/*ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_BUFFER,
4562 &ioctl_msg) < */0)
4563 DEBUG_PRINT_ERROR("\nRelease output buffer failed in VCD");
4564
4565#ifdef _ANDROID_
4566 if(m_enable_android_native_buffers) {
4567 if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4568 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4569 drv_ctx.ptr_outputbuffer[index].mmaped_size);
4570 }
4571 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4572 } else {
4573#endif
4574 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
4575 {
4576 DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
4577 drv_ctx.ptr_outputbuffer[0].pmem_fd);
4578 DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %d",
Shalaj Jain4a9f77d2012-11-01 16:47:33 -07004579 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
Shalaj Jain273b3e02012-06-22 19:08:03 -07004580 drv_ctx.ptr_outputbuffer[0].bufferaddr);
4581 munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
Shalaj Jain4a9f77d2012-11-01 16:47:33 -07004582 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004583 close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
4584 drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
4585#ifdef USE_ION
4586 free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
4587#endif
4588 }
4589#ifdef _ANDROID_
4590 }
4591#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004592 if (release_output_done()) {
4593 free_extradata();
4594 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07004595 }
4596
4597 return OMX_ErrorNone;
4598
4599}
4600
4601OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp,
4602 OMX_BUFFERHEADERTYPE **bufferHdr,
4603 OMX_U32 port,
4604 OMX_PTR appData,
4605 OMX_U32 bytes)
4606{
4607 OMX_BUFFERHEADERTYPE *input = NULL;
4608 unsigned char *buf_addr = NULL;
4609 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4610 unsigned i = 0;
4611
4612 /* Sanity Check*/
4613 if (bufferHdr == NULL)
4614 {
4615 return OMX_ErrorBadParameter;
4616 }
4617
4618 if (m_inp_heap_ptr == NULL)
4619 {
4620 m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4621 calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4622 drv_ctx.ip_buf.actualcount);
4623 m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4624 calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4625 drv_ctx.ip_buf.actualcount);
4626
4627 if (m_inp_heap_ptr == NULL)
4628 {
4629 DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4630 return OMX_ErrorInsufficientResources;
4631 }
4632 }
4633
4634 /*Find a Free index*/
4635 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4636 {
4637 if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
4638 {
4639 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4640 break;
4641 }
4642 }
4643
4644 if (i < drv_ctx.ip_buf.actualcount)
4645 {
4646 buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4647
4648 if (buf_addr == NULL)
4649 {
4650 return OMX_ErrorInsufficientResources;
4651 }
4652
4653 *bufferHdr = (m_inp_heap_ptr + i);
4654 input = *bufferHdr;
4655 BITMASK_SET(&m_heap_inp_bm_count,i);
4656
4657 input->pBuffer = (OMX_U8 *)buf_addr;
4658 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4659 input->nVersion.nVersion = OMX_SPEC_VERSION;
4660 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4661 input->pAppPrivate = appData;
4662 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4663 DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
4664 eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4665 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr [i] );
4666 /*Add the Buffers to freeq*/
4667 if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr [i],NULL,NULL))
4668 {
4669 DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4670 return OMX_ErrorInsufficientResources;
4671 }
4672 }
4673 else
4674 {
4675 return OMX_ErrorBadParameter;
4676 }
4677
4678 return eRet;
4679
4680}
4681
4682
4683/* ======================================================================
4684FUNCTION
4685 omx_vdec::AllocateInputBuffer
4686
4687DESCRIPTION
4688 Helper function for allocate buffer in the input pin
4689
4690PARAMETERS
4691 None.
4692
4693RETURN VALUE
4694 true/false
4695
4696========================================================================== */
4697OMX_ERRORTYPE omx_vdec::allocate_input_buffer(
4698 OMX_IN OMX_HANDLETYPE hComp,
4699 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4700 OMX_IN OMX_U32 port,
4701 OMX_IN OMX_PTR appData,
4702 OMX_IN OMX_U32 bytes)
4703{
4704
4705 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4706 struct vdec_setbuffer_cmd setbuffers;
4707 OMX_BUFFERHEADERTYPE *input = NULL;
4708 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4709 unsigned i = 0;
4710 unsigned char *buf_addr = NULL;
4711 int pmem_fd = -1;
4712
4713 if(bytes != drv_ctx.ip_buf.buffer_size)
4714 {
4715 DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d",
4716 bytes, drv_ctx.ip_buf.buffer_size);
4717 return OMX_ErrorBadParameter;
4718 }
4719
4720 if(!m_inp_mem_ptr)
4721 {
4722 DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4723 drv_ctx.ip_buf.actualcount,
4724 drv_ctx.ip_buf.buffer_size);
4725
4726 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4727 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4728
4729 if (m_inp_mem_ptr == NULL)
4730 {
4731 return OMX_ErrorInsufficientResources;
4732 }
4733
4734 drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4735 calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4736
4737 if (drv_ctx.ptr_inputbuffer == NULL)
4738 {
4739 return OMX_ErrorInsufficientResources;
4740 }
4741#ifdef USE_ION
4742 drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4743 calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4744
4745 if (drv_ctx.ip_buf_ion_info == NULL)
4746 {
4747 return OMX_ErrorInsufficientResources;
4748 }
4749#endif
4750
4751 for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
4752 {
4753 drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4754#ifdef USE_ION
4755 drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4756#endif
4757 }
4758 }
4759
4760 for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
4761 {
4762 if(BITMASK_ABSENT(&m_inp_bm_count,i))
4763 {
4764 DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
4765 break;
4766 }
4767 }
4768
4769 if(i < drv_ctx.ip_buf.actualcount)
4770 {
4771 struct v4l2_buffer buf;
4772 struct v4l2_plane plane;
4773 int rc;
4774 DEBUG_PRINT_LOW("\n Allocate input Buffer");
4775#ifdef USE_ION
4776 drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4777 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4778 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004779 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004780 if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4781 return OMX_ErrorInsufficientResources;
4782 }
4783 pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4784#else
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 if (pmem_fd == 0)
4794 {
4795 pmem_fd = open (MEM_DEVICE,O_RDWR);
4796
4797 if (pmem_fd < 0)
4798 {
4799 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4800 return OMX_ErrorInsufficientResources;
4801 }
4802 }
4803
4804 if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4805 drv_ctx.ip_buf.alignment))
4806 {
4807 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4808 close(pmem_fd);
4809 return OMX_ErrorInsufficientResources;
4810 }
4811#endif
4812 if (!secure_mode) {
4813 buf_addr = (unsigned char *)mmap(NULL,
4814 drv_ctx.ip_buf.buffer_size,
4815 PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4816
4817 if (buf_addr == MAP_FAILED)
4818 {
4819 close(pmem_fd);
4820#ifdef USE_ION
4821 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4822#endif
4823 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4824 return OMX_ErrorInsufficientResources;
4825 }
4826 }
4827 *bufferHdr = (m_inp_mem_ptr + i);
4828 if (secure_mode)
4829 drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4830 else
4831 drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4832 drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4833 drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4834 drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4835 drv_ctx.ptr_inputbuffer [i].offset = 0;
4836
4837
4838 buf.index = i;
4839 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
4840 buf.memory = V4L2_MEMORY_USERPTR;
4841 plane.bytesused = 0;
4842 plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
4843 plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
4844 plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
4845 plane.reserved[1] = 0;
4846 plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
4847 buf.m.planes = &plane;
4848 buf.length = 1;
4849
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07004850 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 -07004851
4852 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
4853
4854 if (rc) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07004855 DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07004856 /*TODO: How to handle this case */
4857 return OMX_ErrorInsufficientResources;
4858 }
4859
4860 input = *bufferHdr;
4861 BITMASK_SET(&m_inp_bm_count,i);
4862 DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
4863 if (secure_mode)
4864 input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4865 else
4866 input->pBuffer = (OMX_U8 *)buf_addr;
4867 input->nSize = sizeof(OMX_BUFFERHEADERTYPE);
4868 input->nVersion.nVersion = OMX_SPEC_VERSION;
4869 input->nAllocLen = drv_ctx.ip_buf.buffer_size;
4870 input->pAppPrivate = appData;
4871 input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
4872 input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4873
4874 if (drv_ctx.disable_dmx)
4875 {
4876 eRet = allocate_desc_buffer(i);
4877 }
4878 }
4879 else
4880 {
4881 DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4882 eRet = OMX_ErrorInsufficientResources;
4883 }
4884 return eRet;
4885}
4886
4887
4888/* ======================================================================
4889FUNCTION
4890 omx_vdec::AllocateOutputBuffer
4891
4892DESCRIPTION
4893 Helper fn for AllocateBuffer in the output pin
4894
4895PARAMETERS
4896 <TBD>.
4897
4898RETURN VALUE
4899 OMX Error None if everything went well.
4900
4901========================================================================== */
4902OMX_ERRORTYPE omx_vdec::allocate_output_buffer(
4903 OMX_IN OMX_HANDLETYPE hComp,
4904 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4905 OMX_IN OMX_U32 port,
4906 OMX_IN OMX_PTR appData,
4907 OMX_IN OMX_U32 bytes)
4908{
4909 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4910 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
4911 unsigned i= 0; // Temporary counter
4912 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4913 struct vdec_setbuffer_cmd setbuffers;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07004914 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07004915#ifdef USE_ION
4916 int ion_device_fd =-1;
4917 struct ion_allocation_data ion_alloc_data;
4918 struct ion_fd_data fd_ion_data;
4919#endif
4920 if(!m_out_mem_ptr)
4921 {
4922 DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4923 drv_ctx.op_buf.actualcount,
4924 drv_ctx.op_buf.buffer_size);
4925 int nBufHdrSize = 0;
4926 int nPlatformEntrySize = 0;
4927 int nPlatformListSize = 0;
4928 int nPMEMInfoSize = 0;
4929 int pmem_fd = -1;
4930 unsigned char *pmem_baseaddress = NULL;
4931
4932 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
4933 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
4934 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
4935
4936 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
4937 drv_ctx.op_buf.actualcount);
4938 nBufHdrSize = drv_ctx.op_buf.actualcount *
4939 sizeof(OMX_BUFFERHEADERTYPE);
4940
4941 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
4942 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4943 nPlatformListSize = drv_ctx.op_buf.actualcount *
4944 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4945 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4946 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
4947
4948 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
4949 sizeof(OMX_BUFFERHEADERTYPE),
4950 nPMEMInfoSize,
4951 nPlatformListSize);
4952 DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
4953 drv_ctx.op_buf.actualcount);
4954#ifdef USE_ION
4955 ion_device_fd = alloc_map_ion_memory(
4956 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
4957 drv_ctx.op_buf.alignment,
Vinay Kalia53fa6832012-10-11 17:55:30 -07004958 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
Shalaj Jain273b3e02012-06-22 19:08:03 -07004959 if (ion_device_fd < 0) {
4960 return OMX_ErrorInsufficientResources;
4961 }
4962 pmem_fd = fd_ion_data.fd;
4963#else
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 if(pmem_fd == 0)
4974 {
4975 pmem_fd = open (MEM_DEVICE,O_RDWR);
4976
4977 if (pmem_fd < 0)
4978 {
4979 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4980 drv_ctx.op_buf.buffer_size);
4981 return OMX_ErrorInsufficientResources;
4982 }
4983 }
4984
4985 if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
4986 drv_ctx.op_buf.actualcount,
4987 drv_ctx.op_buf.alignment))
4988 {
4989 DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4990 close(pmem_fd);
4991 return OMX_ErrorInsufficientResources;
4992 }
4993#endif
4994 if (!secure_mode) {
4995 pmem_baseaddress = (unsigned char *)mmap(NULL,
4996 (drv_ctx.op_buf.buffer_size *
4997 drv_ctx.op_buf.actualcount),
4998 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4999 if (pmem_baseaddress == MAP_FAILED)
5000 {
5001 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
5002 drv_ctx.op_buf.buffer_size);
5003 close(pmem_fd);
5004#ifdef USE_ION
5005 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
5006#endif
5007 return OMX_ErrorInsufficientResources;
5008 }
5009 }
5010 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
5011 // Alloc mem for platform specific info
5012 char *pPtr=NULL;
5013 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
5014 nPMEMInfoSize,1);
5015 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
5016 calloc (sizeof(struct vdec_bufferpayload),
5017 drv_ctx.op_buf.actualcount);
5018 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
5019 calloc (sizeof (struct vdec_output_frameinfo),
5020 drv_ctx.op_buf.actualcount);
5021#ifdef USE_ION
5022 drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
5023 calloc (sizeof(struct vdec_ion),
5024 drv_ctx.op_buf.actualcount);
5025#endif
5026
5027 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
5028 && drv_ctx.ptr_respbuffer)
5029 {
5030 drv_ctx.ptr_outputbuffer[0].mmaped_size =
5031 (drv_ctx.op_buf.buffer_size *
5032 drv_ctx.op_buf.actualcount);
5033 bufHdr = m_out_mem_ptr;
5034 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
5035 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
5036 (((char *) m_platform_list) + nPlatformListSize);
5037 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
5038 (((char *) m_platform_entry) + nPlatformEntrySize);
5039 pPlatformList = m_platform_list;
5040 pPlatformEntry = m_platform_entry;
5041 pPMEMInfo = m_pmem_info;
5042
5043 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
5044
5045 // Settting the entire storage nicely
5046 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
5047 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
5048 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
5049 {
5050 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
5051 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
5052 // Set the values when we determine the right HxW param
5053 bufHdr->nAllocLen = bytes;
5054 bufHdr->nFilledLen = 0;
5055 bufHdr->pAppPrivate = appData;
5056 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
5057 // Platform specific PMEM Information
5058 // Initialize the Platform Entry
5059 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
5060 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5061 pPlatformEntry->entry = pPMEMInfo;
5062 // Initialize the Platform List
5063 pPlatformList->nEntries = 1;
5064 pPlatformList->entryList = pPlatformEntry;
5065 // Keep pBuffer NULL till vdec is opened
5066 bufHdr->pBuffer = NULL;
5067 bufHdr->nOffset = 0;
5068
5069 pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i;
5070 pPMEMInfo->pmem_fd = 0;
5071 bufHdr->pPlatformPrivate = pPlatformList;
5072
5073 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
Vinay Kalia53fa6832012-10-11 17:55:30 -07005074 m_pmem_info[i].pmem_fd = pmem_fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005075#ifdef USE_ION
5076 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
5077 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
5078 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
5079#endif
5080
5081 /*Create a mapping between buffers*/
5082 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
5083 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
5084 &drv_ctx.ptr_outputbuffer[i];
5085 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
5086 drv_ctx.ptr_outputbuffer[i].bufferaddr =
5087 pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
5088
5089 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
5090 pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
5091 drv_ctx.ptr_outputbuffer[i].bufferaddr);
5092 // Move the buffer and buffer header pointers
5093 bufHdr++;
5094 pPMEMInfo++;
5095 pPlatformEntry++;
5096 pPlatformList++;
5097 }
5098 }
5099 else
5100 {
5101 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
5102 m_out_mem_ptr, pPtr);
5103 if(m_out_mem_ptr)
5104 {
5105 free(m_out_mem_ptr);
5106 m_out_mem_ptr = NULL;
5107 }
5108 if(pPtr)
5109 {
5110 free(pPtr);
5111 pPtr = NULL;
5112 }
5113 if(drv_ctx.ptr_outputbuffer)
5114 {
5115 free(drv_ctx.ptr_outputbuffer);
5116 drv_ctx.ptr_outputbuffer = NULL;
5117 }
5118 if(drv_ctx.ptr_respbuffer)
5119 {
5120 free(drv_ctx.ptr_respbuffer);
5121 drv_ctx.ptr_respbuffer = NULL;
5122 }
5123#ifdef USE_ION
5124 if (drv_ctx.op_buf_ion_info) {
5125 DEBUG_PRINT_LOW("\n Free o/p ion context");
5126 free(drv_ctx.op_buf_ion_info);
5127 drv_ctx.op_buf_ion_info = NULL;
5128 }
5129#endif
5130 eRet = OMX_ErrorInsufficientResources;
5131 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005132 if (eRet == OMX_ErrorNone)
5133 eRet = allocate_extradata();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005134 }
5135
5136 for(i=0; i< drv_ctx.op_buf.actualcount; i++)
5137 {
5138 if(BITMASK_ABSENT(&m_out_bm_count,i))
5139 {
5140 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
5141 break;
5142 }
5143 }
5144
5145 if (eRet == OMX_ErrorNone)
5146 {
5147 if(i < drv_ctx.op_buf.actualcount)
5148 {
5149 struct v4l2_buffer buf;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005150 struct v4l2_plane plane[VIDEO_MAX_PLANES];
Shalaj Jain273b3e02012-06-22 19:08:03 -07005151 int rc;
5152 m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
5153
5154 drv_ctx.ptr_outputbuffer[i].buffer_len =
5155 drv_ctx.op_buf.buffer_size;
5156
5157 *bufferHdr = (m_out_mem_ptr + i );
5158 if (secure_mode) {
5159 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
5160 }
5161 drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
5162
5163 buf.index = i;
5164 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5165 buf.memory = V4L2_MEMORY_USERPTR;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005166 plane[0].length = drv_ctx.op_buf.buffer_size;
5167 plane[0].m.userptr = (unsigned long)(drv_ctx.ptr_outputbuffer[i].bufferaddr-drv_ctx.ptr_outputbuffer[i].offset);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005168#ifdef USE_ION
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005169 plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005170#endif
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005171 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
5172 plane[0].data_offset = 0;
5173 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5174 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5175 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5176 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
5177#ifdef USE_ION
5178 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5179#endif
5180 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
5181 plane[extra_idx].data_offset = 0;
5182 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5183 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
5184 return OMX_ErrorBadParameter;
5185 }
5186 buf.m.planes = plane;
5187 buf.length = drv_ctx.num_planes;
5188 DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]);
5189 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
5190 if (rc) {
5191 /*TODO: How to handle this case */
Shalaj Jain273b3e02012-06-22 19:08:03 -07005192 return OMX_ErrorInsufficientResources;
5193 }
5194
5195 if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
5196 enum v4l2_buf_type buf_type;
5197 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5198 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5199 if (rc) {
5200 return OMX_ErrorInsufficientResources;
5201 } else {
5202 streaming[CAPTURE_PORT] = true;
5203 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
5204 }
5205 }
5206
5207 (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5208 (*bufferHdr)->pAppPrivate = appData;
5209 BITMASK_SET(&m_out_bm_count,i);
5210 }
5211 else
5212 {
5213 DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
5214 eRet = OMX_ErrorInsufficientResources;
5215 }
5216 }
5217
5218 return eRet;
5219}
5220
5221
5222// AllocateBuffer -- API Call
5223/* ======================================================================
5224FUNCTION
5225 omx_vdec::AllocateBuffer
5226
5227DESCRIPTION
5228 Returns zero if all the buffers released..
5229
5230PARAMETERS
5231 None.
5232
5233RETURN VALUE
5234 true/false
5235
5236========================================================================== */
5237OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
5238 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5239 OMX_IN OMX_U32 port,
5240 OMX_IN OMX_PTR appData,
5241 OMX_IN OMX_U32 bytes)
5242{
5243 unsigned i = 0;
5244 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5245
5246 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
5247 if(m_state == OMX_StateInvalid)
5248 {
5249 DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5250 return OMX_ErrorInvalidState;
5251 }
5252
5253 if(port == OMX_CORE_INPUT_PORT_INDEX)
5254 {
5255 if (arbitrary_bytes)
5256 {
5257 eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5258 }
5259 else
5260 {
5261 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5262 }
5263 }
5264 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5265 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08005266 eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5267 appData,bytes);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005268 }
5269 else
5270 {
5271 DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5272 eRet = OMX_ErrorBadPortIndex;
5273 }
5274 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5275 if(eRet == OMX_ErrorNone)
5276 {
5277 if(allocate_done()){
5278 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
5279 {
5280 // Send the callback now
5281 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5282 post_event(OMX_CommandStateSet,OMX_StateIdle,
5283 OMX_COMPONENT_GENERATE_EVENT);
5284 }
5285 }
5286 if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
5287 {
5288 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
5289 {
5290 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5291 post_event(OMX_CommandPortEnable,
5292 OMX_CORE_INPUT_PORT_INDEX,
5293 OMX_COMPONENT_GENERATE_EVENT);
5294 }
5295 }
5296 if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
5297 {
5298 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
5299 {
5300 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5301 post_event(OMX_CommandPortEnable,
5302 OMX_CORE_OUTPUT_PORT_INDEX,
5303 OMX_COMPONENT_GENERATE_EVENT);
5304 }
5305 }
5306 }
5307 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
5308 return eRet;
5309}
5310
5311// Free Buffer - API call
5312/* ======================================================================
5313FUNCTION
5314 omx_vdec::FreeBuffer
5315
5316DESCRIPTION
5317
5318PARAMETERS
5319 None.
5320
5321RETURN VALUE
5322 true/false
5323
5324========================================================================== */
5325OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
5326 OMX_IN OMX_U32 port,
5327 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5328{
5329 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5330 unsigned int nPortIndex;
5331 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
5332
5333 if(m_state == OMX_StateIdle &&
5334 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5335 {
5336 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
5337 }
5338 else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5339 (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
5340 {
5341 DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port);
5342 }
5343 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
5344 {
5345 DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5346 post_event(OMX_EventError,
5347 OMX_ErrorPortUnpopulated,
5348 OMX_COMPONENT_GENERATE_EVENT);
5349
5350 return OMX_ErrorIncorrectStateOperation;
5351 }
5352 else if (m_state != OMX_StateInvalid)
5353 {
5354 DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5355 post_event(OMX_EventError,
5356 OMX_ErrorPortUnpopulated,
5357 OMX_COMPONENT_GENERATE_EVENT);
5358 }
5359
5360 if(port == OMX_CORE_INPUT_PORT_INDEX)
5361 {
5362 /*Check if arbitrary bytes*/
5363 if(!arbitrary_bytes && !input_use_buffer)
5364 nPortIndex = buffer - m_inp_mem_ptr;
5365 else
5366 nPortIndex = buffer - m_inp_heap_ptr;
5367
5368 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
5369 if(nPortIndex < drv_ctx.ip_buf.actualcount)
5370 {
5371 // Clear the bit associated with it.
5372 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5373 BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5374 if (input_use_buffer == true)
5375 {
5376
5377 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
5378 if(m_phdr_pmem_ptr)
5379 free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5380 }
5381 else
5382 {
5383 if (arbitrary_bytes)
5384 {
5385 if(m_phdr_pmem_ptr)
5386 free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5387 else
5388 free_input_buffer(nPortIndex,NULL);
5389 }
5390 else
5391 free_input_buffer(buffer);
5392 }
5393 m_inp_bPopulated = OMX_FALSE;
5394 /*Free the Buffer Header*/
5395 if (release_input_done())
5396 {
5397 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
5398 free_input_buffer_header();
5399 }
5400 }
5401 else
5402 {
5403 DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5404 eRet = OMX_ErrorBadPortIndex;
5405 }
5406
5407 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5408 && release_input_done())
5409 {
5410 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5411 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5412 post_event(OMX_CommandPortDisable,
5413 OMX_CORE_INPUT_PORT_INDEX,
5414 OMX_COMPONENT_GENERATE_EVENT);
5415 }
5416 }
5417 else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
5418 {
5419 // check if the buffer is valid
Vinay Kaliada4f4422013-01-09 10:45:03 -08005420 nPortIndex = buffer - client_buffers.get_il_buf_hdr();
Shalaj Jain273b3e02012-06-22 19:08:03 -07005421 if(nPortIndex < drv_ctx.op_buf.actualcount)
5422 {
5423 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
5424 // Clear the bit associated with it.
5425 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5426 m_out_bPopulated = OMX_FALSE;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005427 client_buffers.free_output_buffer (buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005428
5429 if (release_output_done())
5430 {
5431 free_output_buffer_header();
5432 }
5433 }
5434 else
5435 {
5436 DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5437 eRet = OMX_ErrorBadPortIndex;
5438 }
5439 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5440 && release_output_done())
5441 {
5442 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
5443
5444 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
5445 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5446#ifdef _ANDROID_ICS_
5447 if (m_enable_android_native_buffers)
5448 {
5449 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5450 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5451 }
5452#endif
5453
5454 post_event(OMX_CommandPortDisable,
5455 OMX_CORE_OUTPUT_PORT_INDEX,
5456 OMX_COMPONENT_GENERATE_EVENT);
5457 }
5458 }
5459 else
5460 {
5461 eRet = OMX_ErrorBadPortIndex;
5462 }
5463 if((eRet == OMX_ErrorNone) &&
5464 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
5465 {
5466 if(release_done())
5467 {
5468 // Send the callback now
5469 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5470 post_event(OMX_CommandStateSet, OMX_StateLoaded,
5471 OMX_COMPONENT_GENERATE_EVENT);
5472 }
5473 }
5474 return eRet;
5475}
5476
5477
5478/* ======================================================================
5479FUNCTION
5480 omx_vdec::EmptyThisBuffer
5481
5482DESCRIPTION
5483 This routine is used to push the encoded video frames to
5484 the video decoder.
5485
5486PARAMETERS
5487 None.
5488
5489RETURN VALUE
5490 OMX Error None if everything went successful.
5491
5492========================================================================== */
5493OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5494 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5495{
5496 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5497 unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5498
5499 if(m_state == OMX_StateInvalid)
5500 {
5501 DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5502 return OMX_ErrorInvalidState;
5503 }
5504
5505 if (buffer == NULL)
5506 {
5507 DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5508 return OMX_ErrorBadParameter;
5509 }
5510
5511 if (!m_inp_bEnabled)
5512 {
5513 DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5514 return OMX_ErrorIncorrectStateOperation;
5515 }
5516
5517 if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
5518 {
5519 DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %d", buffer->nInputPortIndex);
5520 return OMX_ErrorBadPortIndex;
5521 }
5522
5523#ifdef _ANDROID_
5524 if(iDivXDrmDecrypt)
5525 {
5526 OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5527 if(drmErr != OMX_ErrorNone) {
5528 // this error can be ignored
5529 DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5530 }
5531 }
5532#endif //_ANDROID_
5533 if (perf_flag)
5534 {
5535 if (!latency)
5536 {
5537 dec_time.stop();
5538 latency = dec_time.processing_time_us();
5539 dec_time.start();
5540 }
5541 }
5542
5543 if (arbitrary_bytes)
5544 {
5545 nBufferIndex = buffer - m_inp_heap_ptr;
5546 }
5547 else
5548 {
5549 if (input_use_buffer == true)
5550 {
5551 nBufferIndex = buffer - m_inp_heap_ptr;
5552 m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5553 m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5554 m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5555 buffer = &m_inp_mem_ptr[nBufferIndex];
5556 DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %d",
5557 &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5558 }
5559 else{
5560 nBufferIndex = buffer - m_inp_mem_ptr;
5561 }
5562 }
5563
5564 if (nBufferIndex > drv_ctx.ip_buf.actualcount )
5565 {
5566 DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5567 return OMX_ErrorBadParameter;
5568 }
5569
5570 DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5571 buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5572 if (arbitrary_bytes)
5573 {
5574 post_event ((unsigned)hComp,(unsigned)buffer,
5575 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5576 }
5577 else
5578 {
5579 if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5580 set_frame_rate(buffer->nTimeStamp);
5581 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5582 }
5583 return OMX_ErrorNone;
5584}
5585
5586/* ======================================================================
5587FUNCTION
5588 omx_vdec::empty_this_buffer_proxy
5589
5590DESCRIPTION
5591 This routine is used to push the encoded video frames to
5592 the video decoder.
5593
5594PARAMETERS
5595 None.
5596
5597RETURN VALUE
5598 OMX Error None if everything went successful.
5599
5600========================================================================== */
5601OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
5602 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5603{
5604 int push_cnt = 0,i=0;
5605 unsigned nPortIndex = 0;
5606 OMX_ERRORTYPE ret = OMX_ErrorNone;
5607 struct vdec_input_frameinfo frameinfo;
5608 struct vdec_bufferpayload *temp_buffer;
5609 struct vdec_ioctl_msg ioctl_msg;
5610 struct vdec_seqheader seq_header;
5611 bool port_setting_changed = true;
5612 bool not_coded_vop = false;
5613
5614 /*Should we generate a Aync error event*/
5615 if (buffer == NULL || buffer->pInputPortPrivate == NULL)
5616 {
5617 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5618 return OMX_ErrorBadParameter;
5619 }
5620
5621 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5622
5623 if (nPortIndex > drv_ctx.ip_buf.actualcount)
5624 {
5625 DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5626 nPortIndex);
5627 return OMX_ErrorBadParameter;
5628 }
5629
5630 pending_input_buffers++;
5631
5632 /* return zero length and not an EOS buffer */
5633 if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5634 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
5635 {
5636 DEBUG_PRINT_HIGH("\n return zero legth buffer");
5637 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5638 OMX_COMPONENT_GENERATE_EBD);
5639 return OMX_ErrorNone;
5640 }
5641
5642
5643 if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){
5644 mp4StreamType psBits;
5645 psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5646 psBits.numBytes = buffer->nFilledLen;
5647 mp4_headerparser.parseHeader(&psBits);
5648 not_coded_vop = mp4_headerparser.is_notcodec_vop(
5649 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5650 if(not_coded_vop) {
5651 DEBUG_PRINT_HIGH("\n Found Not coded vop len %d frame number %d",
5652 buffer->nFilledLen,frame_count);
5653 if(buffer->nFlags & OMX_BUFFERFLAG_EOS){
5654 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
5655 not_coded_vop = false;
5656 buffer->nFilledLen = 0;
5657 }
5658 }
5659 }
5660
5661 if(input_flush_progress == true
5662
5663 || not_coded_vop
5664
5665 )
5666 {
5667 DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
5668 post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5669 OMX_COMPONENT_GENERATE_EBD);
5670 return OMX_ErrorNone;
5671 }
5672
5673 temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5674
5675 if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
5676 {
5677 return OMX_ErrorBadParameter;
5678 }
5679
5680 DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5681 /*for use buffer we need to memcpy the data*/
5682 temp_buffer->buffer_len = buffer->nFilledLen;
5683
5684 if (input_use_buffer)
5685 {
5686 if (buffer->nFilledLen <= temp_buffer->buffer_len)
5687 {
5688 if(arbitrary_bytes)
5689 {
5690 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5691 }
5692 else
5693 {
5694 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5695 buffer->nFilledLen);
5696 }
5697 }
5698 else
5699 {
5700 return OMX_ErrorBadParameter;
5701 }
5702
5703 }
5704
5705 frameinfo.bufferaddr = temp_buffer->bufferaddr;
5706 frameinfo.client_data = (void *) buffer;
5707 frameinfo.datalen = temp_buffer->buffer_len;
5708 frameinfo.flags = 0;
5709 frameinfo.offset = buffer->nOffset;
5710 frameinfo.pmem_fd = temp_buffer->pmem_fd;
5711 frameinfo.pmem_offset = temp_buffer->offset;
5712 frameinfo.timestamp = buffer->nTimeStamp;
5713 if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr)
5714 {
5715 DEBUG_PRINT_LOW("ETB: dmx enabled");
5716 if (m_demux_entries == 0)
5717 {
5718 extract_demux_addr_offsets(buffer);
5719 }
5720
5721 DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%d",m_demux_entries);
5722 handle_demux_data(buffer);
5723 frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5724 frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5725 }
5726 else
5727 {
5728 frameinfo.desc_addr = NULL;
5729 frameinfo.desc_size = 0;
5730 }
5731 if(!arbitrary_bytes)
5732 {
5733 frameinfo.flags |= buffer->nFlags;
5734 }
5735
5736#ifdef _ANDROID_
5737 if (m_debug_timestamp)
5738 {
5739 if(arbitrary_bytes)
5740 {
5741 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5742 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5743 }
5744 else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG))
5745 {
5746 DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5747 m_timestamp_list.insert_ts(buffer->nTimeStamp);
5748 }
5749 }
5750#endif
5751
5752#ifdef INPUT_BUFFER_LOG
5753 if (inputBufferFile1)
5754 {
5755 fwrite((const char *)temp_buffer->bufferaddr,
5756 temp_buffer->buffer_len,1,inputBufferFile1);
5757 }
5758#endif
5759
5760 if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
5761 {
5762 frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5763 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5764 }
5765
5766 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5767 {
5768 DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
5769 frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5770 h264_scratch.nFilledLen = 0;
5771 nal_count = 0;
5772 look_ahead_nal = false;
5773 frame_count = 0;
5774 if (m_frame_parser.mutils)
5775 m_frame_parser.mutils->initialize_frame_checking_environment();
5776 m_frame_parser.flush();
5777 h264_last_au_ts = LLONG_MAX;
5778 h264_last_au_flags = 0;
5779 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5780 m_demux_entries = 0;
5781 }
5782 struct v4l2_buffer buf = {0};
5783 struct v4l2_plane plane;
5784 int rc;
5785 unsigned long print_count;
5786 if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
5787 { buf.flags = V4L2_BUF_FLAG_EOS;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005788 DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005789 }
5790 OMX_ERRORTYPE eRet = OMX_ErrorNone;
5791 buf.index = nPortIndex;
5792 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5793 buf.memory = V4L2_MEMORY_USERPTR;
5794 plane.bytesused = temp_buffer->buffer_len;
5795 plane.length = drv_ctx.ip_buf.buffer_size;
5796 plane.m.userptr = (unsigned long)(temp_buffer->bufferaddr-temp_buffer->offset);
5797 plane.reserved[0] = temp_buffer->pmem_fd;
5798 plane.reserved[1] = temp_buffer->offset;
5799 plane.data_offset = 0;
5800 buf.m.planes = &plane;
5801 buf.length = 1;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08005802 if (frameinfo.timestamp >= LLONG_MAX) {
5803 buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
5804 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07005805 //assumption is that timestamp is in milliseconds
5806 buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
5807 buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
Deva Ramasubramanian46a17952012-08-24 11:35:26 -07005808 buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
5809
Shalaj Jain273b3e02012-06-22 19:08:03 -07005810 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
Praneeth Paladugu268314a2012-08-23 11:33:28 -07005811 if(rc)
5812 {
5813 DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
5814 return OMX_ErrorHardware;
5815 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07005816 if(!streaming[OUTPUT_PORT])
5817 {
5818 enum v4l2_buf_type buf_type;
5819 int ret,r;
Vinay Kalia85793762012-06-14 19:12:34 -07005820
Shalaj Jain273b3e02012-06-22 19:08:03 -07005821 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5822 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
5823 ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
5824 if(!ret) {
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005825 DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005826 streaming[OUTPUT_PORT] = true;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005827 } else{
5828 /*TODO: How to handle this case */
Ashray Kulkarni46373df2012-06-05 20:11:31 -07005829 DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
Shalaj Jain273b3e02012-06-22 19:08:03 -07005830 }
5831}
5832 DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5833 frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5834 time_stamp_dts.insert_timestamp(buffer);
5835
5836 return ret;
5837}
5838
5839/* ======================================================================
5840FUNCTION
5841 omx_vdec::FillThisBuffer
5842
5843DESCRIPTION
5844 IL client uses this method to release the frame buffer
5845 after displaying them.
5846
5847PARAMETERS
5848 None.
5849
5850RETURN VALUE
5851 true/false
5852
5853========================================================================== */
5854OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
5855 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5856{
5857
5858 if(m_state == OMX_StateInvalid)
5859 {
5860 DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5861 return OMX_ErrorInvalidState;
5862 }
5863
5864 if (!m_out_bEnabled)
5865 {
5866 DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5867 return OMX_ErrorIncorrectStateOperation;
5868 }
5869
Vinay Kaliada4f4422013-01-09 10:45:03 -08005870 if (buffer == NULL ||
5871 ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount))
Shalaj Jain273b3e02012-06-22 19:08:03 -07005872 {
5873 return OMX_ErrorBadParameter;
5874 }
5875
5876 if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
5877 {
5878 DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %d", buffer->nOutputPortIndex);
5879 return OMX_ErrorBadPortIndex;
5880 }
5881
5882 DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
Vinay Kaliada4f4422013-01-09 10:45:03 -08005883 post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005884 return OMX_ErrorNone;
5885}
5886/* ======================================================================
5887FUNCTION
5888 omx_vdec::fill_this_buffer_proxy
5889
5890DESCRIPTION
5891 IL client uses this method to release the frame buffer
5892 after displaying them.
5893
5894PARAMETERS
5895 None.
5896
5897RETURN VALUE
5898 true/false
5899
5900========================================================================== */
5901OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy(
5902 OMX_IN OMX_HANDLETYPE hComp,
5903 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
5904{
5905 OMX_ERRORTYPE nRet = OMX_ErrorNone;
5906 struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
5907 OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5908 unsigned nPortIndex = 0;
5909 struct vdec_fillbuffer_cmd fillbuffer;
5910 struct vdec_bufferpayload *ptr_outputbuffer = NULL;
5911 struct vdec_output_frameinfo *ptr_respbuffer = NULL;
5912
Vinay Kaliada4f4422013-01-09 10:45:03 -08005913 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
Shalaj Jain273b3e02012-06-22 19:08:03 -07005914
Vinay Kaliada4f4422013-01-09 10:45:03 -08005915 if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
Shalaj Jain273b3e02012-06-22 19:08:03 -07005916 return OMX_ErrorBadParameter;
5917
5918 DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5919 bufferAdd, bufferAdd->pBuffer);
5920 /*Return back the output buffer to client*/
5921 if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
5922 {
5923 DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
5924 buffer->nFilledLen = 0;
5925 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5926 return OMX_ErrorNone;
5927 }
5928 pending_output_buffers++;
Vinay Kaliada4f4422013-01-09 10:45:03 -08005929 buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
Shalaj Jain273b3e02012-06-22 19:08:03 -07005930 ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5931 if (ptr_respbuffer)
5932 {
5933 ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5934 }
5935
5936 if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
5937 {
5938 DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5939 buffer->nFilledLen = 0;
5940 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5941 pending_output_buffers--;
5942 return OMX_ErrorBadParameter;
5943 }
5944
5945 // memcpy (&fillbuffer.buffer,ptr_outputbuffer,\
5946 sizeof(struct vdec_bufferpayload));
5947 // fillbuffer.client_data = bufferAdd;
5948
5949#ifdef _ANDROID_ICS_
5950 if (m_enable_android_native_buffers)
5951 {
5952 // Acquire a write lock on this buffer.
5953 if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
5954 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
5955 DEBUG_PRINT_ERROR("Failed to acquire genlock");
5956 buffer->nFilledLen = 0;
5957 m_cb.FillBufferDone (hComp,m_app_data,buffer);
5958 pending_output_buffers--;
5959 return OMX_ErrorInsufficientResources;
5960 } else {
5961 native_buffer[buffer - m_out_mem_ptr].inuse = true;
5962 }
5963 }
5964#endif
5965 int rc = 0;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005966 struct v4l2_buffer buf={0};
5967 struct v4l2_plane plane[VIDEO_MAX_PLANES];
5968 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07005969
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07005970 buf.index = nPortIndex;
5971 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5972 buf.memory = V4L2_MEMORY_USERPTR;
5973 plane[0].bytesused = buffer->nFilledLen;
5974 plane[0].length = drv_ctx.op_buf.buffer_size;
5975 plane[0].m.userptr = (unsigned long)(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr-drv_ctx.ptr_outputbuffer[nPortIndex].offset);
5976 plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
5977 plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
5978 plane[0].data_offset = 0;
5979 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
5980 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
5981 plane[extra_idx].bytesused = 0;
5982 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
5983 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
5984#ifdef USE_ION
5985 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
5986#endif
5987 plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
5988 plane[extra_idx].data_offset = 0;
5989 } else if (extra_idx >= VIDEO_MAX_PLANES) {
5990 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
5991 return OMX_ErrorBadParameter;
5992 }
5993 buf.m.planes = plane;
5994 buf.length = drv_ctx.num_planes;
5995 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
5996 if (rc) {
5997 /*TODO: How to handle this case */
5998 DEBUG_PRINT_ERROR("Failed to qbuf to driver");
5999 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006000//#ifdef _ANDROID_ICS_
6001 // if (m_enable_android_native_buffers)
6002 // {
6003 // Unlock the buffer
6004 // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6005 // DEBUG_PRINT_ERROR("Releasing genlock failed");
6006 // return OMX_ErrorInsufficientResources;
6007 /// } else {
6008 // native_buffer[buffer - m_out_mem_ptr].inuse = false;
6009 // }
6010 // }
6011//#endif
6012 //m_cb.FillBufferDone (hComp,m_app_data,buffer);
6013 // pending_output_buffers--;
6014 // return OMX_ErrorBadParameter;
6015 //}
6016 return OMX_ErrorNone;
6017}
6018
6019/* ======================================================================
6020FUNCTION
6021 omx_vdec::SetCallbacks
6022
6023DESCRIPTION
6024 Set the callbacks.
6025
6026PARAMETERS
6027 None.
6028
6029RETURN VALUE
6030 OMX Error None if everything successful.
6031
6032========================================================================== */
6033OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
6034 OMX_IN OMX_CALLBACKTYPE* callbacks,
6035 OMX_IN OMX_PTR appData)
6036{
6037
6038 m_cb = *callbacks;
6039 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
6040 m_cb.EventHandler,m_cb.FillBufferDone);
6041 m_app_data = appData;
6042 return OMX_ErrorNotImplemented;
6043}
6044
6045/* ======================================================================
6046FUNCTION
6047 omx_vdec::ComponentDeInit
6048
6049DESCRIPTION
6050 Destroys the component and release memory allocated to the heap.
6051
6052PARAMETERS
6053 <TBD>.
6054
6055RETURN VALUE
6056 OMX Error None if everything successful.
6057
6058========================================================================== */
6059OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
6060{
6061#ifdef _ANDROID_
6062 if(iDivXDrmDecrypt)
6063 {
6064 delete iDivXDrmDecrypt;
6065 iDivXDrmDecrypt=NULL;
6066 }
6067#endif //_ANDROID_
6068
6069 int i = 0;
6070 if (OMX_StateLoaded != m_state)
6071 {
6072 DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
6073 m_state);
6074 DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
6075 }
6076 else
6077 {
6078 DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
6079 }
6080
6081 /*Check if the output buffers have to be cleaned up*/
6082 if(m_out_mem_ptr)
6083 {
6084 DEBUG_PRINT_LOW("Freeing the Output Memory\n");
6085 for (i=0; i < drv_ctx.op_buf.actualcount; i++ )
6086 {
6087 free_output_buffer (&m_out_mem_ptr[i]);
6088#ifdef _ANDROID_ICS_
6089 if (m_enable_android_native_buffers)
6090 {
6091 if (native_buffer[i].inuse)
6092 {
6093 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
6094 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6095 }
6096 native_buffer[i].inuse = false;
6097 }
6098 }
6099#endif
6100 }
6101#ifdef _ANDROID_ICS_
6102 memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
6103#endif
6104 }
6105
6106 /*Check if the input buffers have to be cleaned up*/
6107 if(m_inp_mem_ptr || m_inp_heap_ptr)
6108 {
6109 DEBUG_PRINT_LOW("Freeing the Input Memory\n");
6110 for (i=0; i<drv_ctx.ip_buf.actualcount; i++ )
6111 {
6112 if (m_inp_mem_ptr)
6113 free_input_buffer (i,&m_inp_mem_ptr[i]);
6114 else
6115 free_input_buffer (i,NULL);
6116 }
6117 }
6118 free_input_buffer_header();
6119 free_output_buffer_header();
6120 if(h264_scratch.pBuffer)
6121 {
6122 free(h264_scratch.pBuffer);
6123 h264_scratch.pBuffer = NULL;
6124 }
6125
6126 if (h264_parser)
6127 {
6128 delete h264_parser;
6129 h264_parser = NULL;
6130 }
6131
6132 if(m_platform_list)
6133 {
6134 free(m_platform_list);
6135 m_platform_list = NULL;
6136 }
6137 if(m_vendor_config.pData)
6138 {
6139 free(m_vendor_config.pData);
6140 m_vendor_config.pData = NULL;
6141 }
6142
6143 // Reset counters in mesg queues
6144 m_ftb_q.m_size=0;
6145 m_cmd_q.m_size=0;
6146 m_etb_q.m_size=0;
6147 m_ftb_q.m_read = m_ftb_q.m_write =0;
6148 m_cmd_q.m_read = m_cmd_q.m_write =0;
6149 m_etb_q.m_read = m_etb_q.m_write =0;
6150#ifdef _ANDROID_
6151 if (m_debug_timestamp)
6152 {
6153 m_timestamp_list.reset_ts_list();
6154 }
6155#endif
6156
6157 DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
6158 //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
6159 // NULL);
6160 DEBUG_PRINT_HIGH("\n Close the driver instance");
6161
6162#ifdef INPUT_BUFFER_LOG
6163 fclose (inputBufferFile1);
6164#endif
6165#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006166 if (outputBufferFile1)
6167 fclose (outputBufferFile1);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006168#endif
6169#ifdef OUTPUT_EXTRADATA_LOG
6170 fclose (outputExtradataFile);
6171#endif
6172 DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
6173 return OMX_ErrorNone;
6174}
6175
6176/* ======================================================================
6177FUNCTION
6178 omx_vdec::UseEGLImage
6179
6180DESCRIPTION
6181 OMX Use EGL Image method implementation <TBD>.
6182
6183PARAMETERS
6184 <TBD>.
6185
6186RETURN VALUE
6187 Not Implemented error.
6188
6189========================================================================== */
6190OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
6191 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
6192 OMX_IN OMX_U32 port,
6193 OMX_IN OMX_PTR appData,
6194 OMX_IN void* eglImage)
6195{
6196 OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
6197 OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
6198 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
6199
6200#ifdef USE_EGL_IMAGE_GPU
6201 PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
6202 EGLint fd = -1, offset = 0,pmemPtr = 0;
6203#else
6204 int fd = -1, offset = 0;
6205#endif
6206 DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
6207 if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
6208 DEBUG_PRINT_ERROR("\n ");
6209 }
6210#ifdef USE_EGL_IMAGE_GPU
6211 if(m_display_id == NULL) {
6212 DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
6213 return OMX_ErrorInsufficientResources;
6214 }
6215 egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
6216 eglGetProcAddress("eglQueryImageKHR");
6217 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
6218 egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
6219 egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
6220#else //with OMX test app
6221 struct temp_egl {
6222 int pmem_fd;
6223 int offset;
6224 };
6225 struct temp_egl *temp_egl_id = NULL;
6226 void * pmemPtr = (void *) eglImage;
6227 temp_egl_id = (struct temp_egl *)eglImage;
6228 if (temp_egl_id != NULL)
6229 {
6230 fd = temp_egl_id->pmem_fd;
6231 offset = temp_egl_id->offset;
6232 }
6233#endif
6234 if (fd < 0) {
6235 DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd);
6236 return OMX_ErrorInsufficientResources;
6237 }
6238 pmem_info.pmem_fd = (OMX_U32) fd;
6239 pmem_info.offset = (OMX_U32) offset;
6240 pmem_entry.entry = (void *) &pmem_info;
6241 pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
6242 pmem_list.entryList = &pmem_entry;
6243 pmem_list.nEntries = 1;
6244 ouput_egl_buffers = true;
6245 if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
6246 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
6247 (OMX_U8 *)pmemPtr)) {
6248 DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
6249 return OMX_ErrorInsufficientResources;
6250 }
6251 return OMX_ErrorNone;
6252}
6253
6254/* ======================================================================
6255FUNCTION
6256 omx_vdec::ComponentRoleEnum
6257
6258DESCRIPTION
6259 OMX Component Role Enum method implementation.
6260
6261PARAMETERS
6262 <TBD>.
6263
6264RETURN VALUE
6265 OMX Error None if everything is successful.
6266========================================================================== */
6267OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6268 OMX_OUT OMX_U8* role,
6269 OMX_IN OMX_U32 index)
6270{
6271 OMX_ERRORTYPE eRet = OMX_ErrorNone;
6272
6273 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
6274 {
6275 if((0 == index) && role)
6276 {
6277 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6278 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6279 }
6280 else
6281 {
6282 eRet = OMX_ErrorNoMore;
6283 }
6284 }
6285 if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE))
6286 {
6287 if((0 == index) && role)
6288 {
6289 strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6290 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6291 }
6292 else
6293 {
6294 eRet = OMX_ErrorNoMore;
6295 }
6296 }
6297 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
6298 {
6299 if((0 == index) && role)
6300 {
6301 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6302 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6303 }
6304 else
6305 {
6306 DEBUG_PRINT_LOW("\n No more roles \n");
6307 eRet = OMX_ErrorNoMore;
6308 }
6309 }
6310
6311 else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6312 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6313 )
6314
6315 {
6316 if((0 == index) && role)
6317 {
6318 strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6319 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6320 }
6321 else
6322 {
6323 DEBUG_PRINT_LOW("\n No more roles \n");
6324 eRet = OMX_ErrorNoMore;
6325 }
6326 }
6327 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
6328 {
6329 if((0 == index) && role)
6330 {
6331 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6332 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6333 }
6334 else
6335 {
6336 DEBUG_PRINT_LOW("\n No more roles \n");
6337 eRet = OMX_ErrorNoMore;
6338 }
6339 }
6340 else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6341 (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6342 )
6343 {
6344 if((0 == index) && role)
6345 {
6346 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6347 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6348 }
6349 else
6350 {
6351 DEBUG_PRINT_LOW("\n No more roles \n");
6352 eRet = OMX_ErrorNoMore;
6353 }
6354 }
Praneeth Paladugue0c3b5e2012-07-11 11:49:57 -07006355 else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE))
6356 {
6357 if((0 == index) && role)
6358 {
6359 strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
6360 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
6361 }
6362 else
6363 {
6364 DEBUG_PRINT_LOW("\n No more roles \n");
6365 eRet = OMX_ErrorNoMore;
6366 }
6367 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006368 else
6369 {
6370 DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
6371 eRet = OMX_ErrorInvalidComponentName;
6372 }
6373 return eRet;
6374}
6375
6376
6377
6378
6379/* ======================================================================
6380FUNCTION
6381 omx_vdec::AllocateDone
6382
6383DESCRIPTION
6384 Checks if entire buffer pool is allocated by IL Client or not.
6385 Need this to move to IDLE state.
6386
6387PARAMETERS
6388 None.
6389
6390RETURN VALUE
6391 true/false.
6392
6393========================================================================== */
6394bool omx_vdec::allocate_done(void)
6395{
6396 bool bRet = false;
6397 bool bRet_In = false;
6398 bool bRet_Out = false;
6399
6400 bRet_In = allocate_input_done();
6401 bRet_Out = allocate_output_done();
6402
6403 if(bRet_In && bRet_Out)
6404 {
6405 bRet = true;
6406 }
6407
6408 return bRet;
6409}
6410/* ======================================================================
6411FUNCTION
6412 omx_vdec::AllocateInputDone
6413
6414DESCRIPTION
6415 Checks if I/P buffer pool is allocated by IL Client or not.
6416
6417PARAMETERS
6418 None.
6419
6420RETURN VALUE
6421 true/false.
6422
6423========================================================================== */
6424bool omx_vdec::allocate_input_done(void)
6425{
6426 bool bRet = false;
6427 unsigned i=0;
6428
6429 if (m_inp_mem_ptr == NULL)
6430 {
6431 return bRet;
6432 }
6433 if(m_inp_mem_ptr )
6434 {
6435 for(;i<drv_ctx.ip_buf.actualcount;i++)
6436 {
6437 if(BITMASK_ABSENT(&m_inp_bm_count,i))
6438 {
6439 break;
6440 }
6441 }
6442 }
6443 if(i == drv_ctx.ip_buf.actualcount)
6444 {
6445 bRet = true;
6446 DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6447 }
6448 if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
6449 {
6450 m_inp_bPopulated = OMX_TRUE;
6451 }
6452 return bRet;
6453}
6454/* ======================================================================
6455FUNCTION
6456 omx_vdec::AllocateOutputDone
6457
6458DESCRIPTION
6459 Checks if entire O/P buffer pool is allocated by IL Client or not.
6460
6461PARAMETERS
6462 None.
6463
6464RETURN VALUE
6465 true/false.
6466
6467========================================================================== */
6468bool omx_vdec::allocate_output_done(void)
6469{
6470 bool bRet = false;
6471 unsigned j=0;
6472
6473 if (m_out_mem_ptr == NULL)
6474 {
6475 return bRet;
6476 }
6477
6478 if (m_out_mem_ptr)
6479 {
6480 for(;j < drv_ctx.op_buf.actualcount;j++)
6481 {
6482 if(BITMASK_ABSENT(&m_out_bm_count,j))
6483 {
6484 break;
6485 }
6486 }
6487 }
6488
6489 if(j == drv_ctx.op_buf.actualcount)
6490 {
6491 bRet = true;
6492 DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6493 if(m_out_bEnabled)
6494 m_out_bPopulated = OMX_TRUE;
6495 }
6496
6497 return bRet;
6498}
6499
6500/* ======================================================================
6501FUNCTION
6502 omx_vdec::ReleaseDone
6503
6504DESCRIPTION
6505 Checks if IL client has released all the buffers.
6506
6507PARAMETERS
6508 None.
6509
6510RETURN VALUE
6511 true/false
6512
6513========================================================================== */
6514bool omx_vdec::release_done(void)
6515{
6516 bool bRet = false;
6517
6518 if(release_input_done())
6519 {
6520 if(release_output_done())
6521 {
6522 bRet = true;
6523 }
6524 }
6525 return bRet;
6526}
6527
6528
6529/* ======================================================================
6530FUNCTION
6531 omx_vdec::ReleaseOutputDone
6532
6533DESCRIPTION
6534 Checks if IL client has released all the buffers.
6535
6536PARAMETERS
6537 None.
6538
6539RETURN VALUE
6540 true/false
6541
6542========================================================================== */
6543bool omx_vdec::release_output_done(void)
6544{
6545 bool bRet = false;
6546 unsigned i=0,j=0;
6547
6548 DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6549 if(m_out_mem_ptr)
6550 {
6551 for(;j < drv_ctx.op_buf.actualcount ; j++)
6552 {
6553 if(BITMASK_PRESENT(&m_out_bm_count,j))
6554 {
6555 break;
6556 }
6557 }
6558 if(j == drv_ctx.op_buf.actualcount)
6559 {
6560 m_out_bm_count = 0;
6561 bRet = true;
6562 }
6563 }
6564 else
6565 {
6566 m_out_bm_count = 0;
6567 bRet = true;
6568 }
6569 return bRet;
6570}
6571/* ======================================================================
6572FUNCTION
6573 omx_vdec::ReleaseInputDone
6574
6575DESCRIPTION
6576 Checks if IL client has released all the buffers.
6577
6578PARAMETERS
6579 None.
6580
6581RETURN VALUE
6582 true/false
6583
6584========================================================================== */
6585bool omx_vdec::release_input_done(void)
6586{
6587 bool bRet = false;
6588 unsigned i=0,j=0;
6589
6590 DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6591 if(m_inp_mem_ptr)
6592 {
6593 for(;j<drv_ctx.ip_buf.actualcount;j++)
6594 {
6595 if( BITMASK_PRESENT(&m_inp_bm_count,j))
6596 {
6597 break;
6598 }
6599 }
6600 if(j==drv_ctx.ip_buf.actualcount)
6601 {
6602 bRet = true;
6603 }
6604 }
6605 else
6606 {
6607 bRet = true;
6608 }
6609 return bRet;
6610}
6611
6612OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6613 OMX_BUFFERHEADERTYPE * buffer)
6614{
6615 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6616 if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
6617 {
6618 DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6619 return OMX_ErrorBadParameter;
6620 }
6621 else if (output_flush_progress)
6622 {
6623 DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6624 buffer->nFilledLen = 0;
6625 buffer->nTimeStamp = 0;
6626 buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6627 buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6628 buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6629 }
6630
6631 DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6632 buffer, buffer->pBuffer);
6633 pending_output_buffers --;
6634
6635 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6636 {
6637 DEBUG_PRINT_HIGH("\n Output EOS has been reached");
6638 if (!output_flush_progress)
6639 post_event(NULL,NULL,OMX_COMPONENT_GENERATE_EOS_DONE);
6640
6641 if (psource_frame)
6642 {
6643 m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6644 psource_frame = NULL;
6645 }
6646 if (pdest_frame)
6647 {
6648 pdest_frame->nFilledLen = 0;
6649 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
6650 pdest_frame = NULL;
6651 }
6652 }
6653
6654 DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
6655#ifdef OUTPUT_BUFFER_LOG
Vinay Kalia29beebd2012-10-16 20:06:26 -07006656 if (outputBufferFile1 && buffer->nFilledLen)
Shalaj Jain273b3e02012-06-22 19:08:03 -07006657 {
Vinay Kalia29beebd2012-10-16 20:06:26 -07006658 int buf_index = buffer - m_out_mem_ptr;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006659 int stride = drv_ctx.video_resolution.stride;
6660 int scanlines = drv_ctx.video_resolution.scan_lines;
6661 char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006662 int i;
6663 int bytes_written = 0;
6664 for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
6665 bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6666 temp += stride;
6667 }
6668 temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08006669 int stride_c = stride;
Vinay Kalia29beebd2012-10-16 20:06:26 -07006670 for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
6671 bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
6672 temp += stride_c;
6673 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006674 }
6675#endif
6676
6677 /* For use buffer we need to copy the data */
6678 if (!output_flush_progress)
6679 {
6680 time_stamp_dts.get_next_timestamp(buffer,
6681 (drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6682 ?true:false);
6683 }
6684 if (m_cb.FillBufferDone)
6685 {
6686 if (buffer->nFilledLen > 0)
6687 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07006688 handle_extradata(buffer);
Shalaj Jain273b3e02012-06-22 19:08:03 -07006689 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6690 // Keep min timestamp interval to handle corrupted bit stream scenario
6691 set_frame_rate(buffer->nTimeStamp);
6692 else if (arbitrary_bytes)
6693 adjust_timestamp(buffer->nTimeStamp);
6694 if (perf_flag)
6695 {
6696 if (!proc_frms)
6697 {
6698 dec_time.stop();
6699 latency = dec_time.processing_time_us() - latency;
6700 DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6701 dec_time.start();
6702 fps_metrics.start();
6703 }
6704 proc_frms++;
6705 if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
6706 {
6707 OMX_U64 proc_time = 0;
6708 fps_metrics.stop();
6709 proc_time = fps_metrics.processing_time_us();
6710 DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6711 proc_frms, (float)proc_time / 1e6,
6712 (float)(1e6 * proc_frms) / proc_time);
6713 proc_frms = 0;
6714 }
6715 }
6716
6717#ifdef OUTPUT_EXTRADATA_LOG
6718 if (outputExtradataFile)
6719 {
6720
6721 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6722 p_extra = (OMX_OTHER_EXTRADATATYPE *)
6723 ((unsigned)(buffer->pBuffer + buffer->nOffset +
6724 buffer->nFilledLen + 3)&(~3));
6725 while(p_extra &&
6726 (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) )
6727 {
6728 DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6729 fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6730 if (p_extra->eType == OMX_ExtraDataNone)
6731 {
6732 break;
6733 }
6734 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6735 }
6736 }
6737#endif
6738 }
6739 if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
6740 prev_ts = LLONG_MAX;
6741 rst_prev_ts = true;
6742 }
6743
6744 pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6745 ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6746 buffer->pPlatformPrivate)->entryList->entry;
6747 DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd);
6748#ifdef _ANDROID_ICS_
6749 if (m_enable_android_native_buffers)
6750 {
6751 if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6752 if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6753 DEBUG_PRINT_ERROR("Unlocking genlock failed");
6754 return OMX_ErrorInsufficientResources;
6755 }
6756 else {
6757 native_buffer[buffer - m_out_mem_ptr].inuse = false;
6758 }
6759 }
6760 }
6761#endif
Vinay Kaliada4f4422013-01-09 10:45:03 -08006762 OMX_BUFFERHEADERTYPE *il_buffer;
6763 il_buffer = client_buffers.get_il_buf_hdr(buffer);
6764 if (il_buffer)
6765 m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6766 else {
6767 DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6768 return OMX_ErrorBadParameter;
6769 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006770 DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd);
6771 }
6772 else
6773 {
6774 return OMX_ErrorBadParameter;
6775 }
6776
6777 return OMX_ErrorNone;
6778}
6779
6780OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
6781 OMX_BUFFERHEADERTYPE* buffer)
6782{
6783
6784 if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
6785 {
6786 DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
6787 return OMX_ErrorBadParameter;
6788 }
6789
6790 DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6791 buffer, buffer->pBuffer);
6792 pending_input_buffers--;
6793
6794 if (arbitrary_bytes)
6795 {
6796 if (pdest_frame == NULL && input_flush_progress == false)
6797 {
6798 DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
6799 pdest_frame = buffer;
6800 buffer->nFilledLen = 0;
6801 buffer->nTimeStamp = LLONG_MAX;
6802 push_input_buffer (hComp);
6803 }
6804 else
6805 {
6806 DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
6807 buffer->nFilledLen = 0;
6808 if (!m_input_free_q.insert_entry((unsigned)buffer,NULL,NULL))
6809 {
6810 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6811 }
6812 }
6813 }
6814 else if(m_cb.EmptyBufferDone)
6815 {
6816 buffer->nFilledLen = 0;
6817 if (input_use_buffer == true){
6818 buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6819 }
6820 m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6821 }
6822 return OMX_ErrorNone;
6823}
6824
Shalaj Jain273b3e02012-06-22 19:08:03 -07006825int omx_vdec::async_message_process (void *context, void* message)
6826{
6827 omx_vdec* omx = NULL;
6828 struct vdec_msginfo *vdec_msg = NULL;
6829 OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6830 struct v4l2_buffer *v4l2_buf_ptr=NULL;
6831 struct vdec_output_frameinfo *output_respbuf = NULL;
6832 int rc=1;
6833 if (context == NULL || message == NULL)
6834 {
6835 DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6836 return -1;
6837 }
6838 vdec_msg = (struct vdec_msginfo *)message;
6839
6840 omx = reinterpret_cast<omx_vdec*>(context);
6841
6842#ifdef _ANDROID_
6843 if (omx->m_debug_timestamp)
6844 {
6845 if ( (vdec_msg->msgcode == VDEC_MSG_RESP_OUTPUT_BUFFER_DONE) &&
6846 !(omx->output_flush_progress) )
6847 {
6848 OMX_TICKS expected_ts = 0;
6849 omx->m_timestamp_list.pop_min_ts(expected_ts);
6850 DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6851 vdec_msg->msgdata.output_frame.time_stamp, expected_ts);
6852
6853 if (vdec_msg->msgdata.output_frame.time_stamp != expected_ts)
6854 {
6855 DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6856 }
6857 }
6858 }
6859#endif
6860
6861 switch (vdec_msg->msgcode)
6862 {
6863
6864 case VDEC_MSG_EVT_HW_ERROR:
6865 omx->post_event (NULL,vdec_msg->status_code,\
6866 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6867 break;
6868
6869 case VDEC_MSG_RESP_START_DONE:
6870 omx->post_event (NULL,vdec_msg->status_code,\
6871 OMX_COMPONENT_GENERATE_START_DONE);
6872 break;
6873
6874 case VDEC_MSG_RESP_STOP_DONE:
6875 omx->post_event (NULL,vdec_msg->status_code,\
6876 OMX_COMPONENT_GENERATE_STOP_DONE);
6877 break;
6878
6879 case VDEC_MSG_RESP_RESUME_DONE:
6880 omx->post_event (NULL,vdec_msg->status_code,\
6881 OMX_COMPONENT_GENERATE_RESUME_DONE);
6882 break;
6883
6884 case VDEC_MSG_RESP_PAUSE_DONE:
6885 omx->post_event (NULL,vdec_msg->status_code,\
6886 OMX_COMPONENT_GENERATE_PAUSE_DONE);
6887 break;
6888
6889 case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6890 omx->post_event (NULL,vdec_msg->status_code,\
6891 OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6892 break;
6893 case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6894 omx->post_event (NULL,vdec_msg->status_code,\
6895 OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6896 break;
6897 case VDEC_MSG_RESP_INPUT_FLUSHED:
6898 case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6899
6900 // omxhdr = (OMX_BUFFERHEADERTYPE* ) \
6901 // vdec_msg->msgdata.input_frame_clientdata;
6902
6903 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
6904 omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
6905 if (omxhdr == NULL ||
6906 ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
6907 {
6908 omxhdr = NULL;
6909 vdec_msg->status_code = VDEC_S_EFATAL;
6910 }
6911
6912 omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6913 OMX_COMPONENT_GENERATE_EBD);
6914 break;
6915 case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6916 int64_t *timestamp;
6917 timestamp = (int64_t *) malloc(sizeof(int64_t));
6918 if (timestamp) {
6919 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6920 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6921 OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6922 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
6923 vdec_msg->msgdata.output_frame.time_stamp);
6924 }
6925 break;
6926 case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6927 case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6928
6929 v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
6930 omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
6931 DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6932 omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6933 vdec_msg->msgdata.output_frame.pic_type);
6934
6935 if (omxhdr && omxhdr->pOutputPortPrivate &&
6936 ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6937 (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6938 - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
6939 {
6940 if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
6941 {
6942 omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6943 omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07006944 omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006945 omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
6946
6947 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)
6948 {
6949 omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
6950 //rc = -1;
6951 }
Vinay Kalia592e4b42012-12-19 15:55:47 -08006952 if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ)
6953 {
6954 omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6955 }
6956 vdec_msg->msgdata.output_frame.bufferaddr=omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
6957 if (omxhdr->nFilledLen && ((omx->rectangle.nLeft != vdec_msg->msgdata.output_frame.framesize.left)
6958 || (omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
6959 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
6960 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
6961 omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
6962 omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
6963 omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
6964 omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
6965 DEBUG_PRINT_HIGH("\n Crop information has changed\n");
6966 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
6967 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6968 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006969 output_respbuf = (struct vdec_output_frameinfo *)\
6970 omxhdr->pOutputPortPrivate;
Shalaj Jain273b3e02012-06-22 19:08:03 -07006971 output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6972 output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08006973 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME)
6974 {
6975 output_respbuf->pic_type = PICTURE_TYPE_I;
6976 }
6977 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME)
6978 {
6979 output_respbuf->pic_type = PICTURE_TYPE_P;
6980 }
6981 if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
6982 output_respbuf->pic_type = PICTURE_TYPE_B;
6983 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07006984
6985 if (omx->output_use_buffer)
6986 memcpy ( omxhdr->pBuffer,
6987 (vdec_msg->msgdata.output_frame.bufferaddr +
6988 vdec_msg->msgdata.output_frame.offset),
6989 vdec_msg->msgdata.output_frame.len );
6990 }
6991 else
6992 omxhdr->nFilledLen = 0;
6993 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6994 OMX_COMPONENT_GENERATE_FBD);
6995 }
6996 else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6997 omx->post_event (NULL, vdec_msg->status_code,
6998 OMX_COMPONENT_GENERATE_EOS_DONE);
6999 else
7000 omx->post_event (NULL, vdec_msg->status_code,
7001 OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
7002 break;
7003 case VDEC_MSG_EVT_CONFIG_CHANGED:
7004 DEBUG_PRINT_HIGH("\n Port settings changed");
Vinay Kalia592e4b42012-12-19 15:55:47 -08007005 omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
7006 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007007 break;
7008 case VDEC_MSG_EVT_INFO_CONFIG_CHANGED:
7009 {
7010 DEBUG_PRINT_HIGH("\n Port settings changed info");
7011 // get_buffer_req and populate port defn structure
7012 OMX_ERRORTYPE eRet = OMX_ErrorNone;
Praneeth Paladugu1662ca62012-10-15 13:27:16 -07007013 struct v4l2_format fmt;
7014 int ret;
7015 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7016 ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
Vinay Kalia592e4b42012-12-19 15:55:47 -08007017 omx->update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height);
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08007018 omx->drv_ctx.video_resolution.stride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
7019 omx->drv_ctx.video_resolution.scan_lines = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
Shalaj Jain273b3e02012-06-22 19:08:03 -07007020 omx->m_port_def.nPortIndex = 1;
7021 eRet = omx->update_portdef(&(omx->m_port_def));
Praneeth Paladuguea69de02012-10-30 11:40:17 -07007022 omx->post_event (NULL,vdec_msg->status_code,\
7023 OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007024 break;
7025 }
7026 default:
7027 break;
7028 }
7029 return rc;
7030}
7031
7032OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
7033 OMX_HANDLETYPE hComp,
7034 OMX_BUFFERHEADERTYPE *buffer
7035 )
7036{
7037 unsigned address,p2,id;
7038 DEBUG_PRINT_LOW("\n Empty this arbitrary");
7039
7040 if (buffer == NULL)
7041 {
7042 return OMX_ErrorBadParameter;
7043 }
7044 DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
7045 DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %u, flags %d, timestamp %u",
7046 buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp);
7047
7048 /* return zero length and not an EOS buffer */
7049 /* return buffer if input flush in progress */
7050 if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
7051 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)))
7052 {
7053 DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
7054 m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
7055 return OMX_ErrorNone;
7056 }
7057
7058 if (psource_frame == NULL)
7059 {
7060 DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp);
7061 psource_frame = buffer;
7062 DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
7063 push_input_buffer (hComp);
7064 }
7065 else
7066 {
7067 DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
7068 if (!m_input_pending_q.insert_entry((unsigned)buffer,NULL,NULL))
7069 {
7070 return OMX_ErrorBadParameter;
7071 }
7072 }
7073
7074
7075 return OMX_ErrorNone;
7076}
7077
7078OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
7079{
7080 unsigned address,p2,id;
7081 OMX_ERRORTYPE ret = OMX_ErrorNone;
7082
7083 if (pdest_frame == NULL || psource_frame == NULL)
7084 {
7085 /*Check if we have a destination buffer*/
7086 if (pdest_frame == NULL)
7087 {
7088 DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
7089 if (m_input_free_q.m_size)
7090 {
7091 m_input_free_q.pop_entry(&address,&p2,&id);
7092 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
7093 pdest_frame->nFilledLen = 0;
7094 pdest_frame->nTimeStamp = LLONG_MAX;
7095 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
7096 }
7097 }
7098
7099 /*Check if we have a destination buffer*/
7100 if (psource_frame == NULL)
7101 {
7102 DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
7103 if (m_input_pending_q.m_size)
7104 {
7105 m_input_pending_q.pop_entry(&address,&p2,&id);
7106 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
7107 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
7108 psource_frame->nTimeStamp);
7109 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
7110 psource_frame->nFlags,psource_frame->nFilledLen);
7111
7112 }
7113 }
7114
7115 }
7116
7117 while ((pdest_frame != NULL) && (psource_frame != NULL))
7118 {
7119 switch (codec_type_parse)
7120 {
7121 case CODEC_TYPE_MPEG4:
7122 case CODEC_TYPE_H263:
7123 case CODEC_TYPE_MPEG2:
7124 ret = push_input_sc_codec(hComp);
7125 break;
7126 case CODEC_TYPE_H264:
7127 ret = push_input_h264(hComp);
7128 break;
7129 case CODEC_TYPE_VC1:
7130 ret = push_input_vc1(hComp);
7131 break;
7132 }
7133 if (ret != OMX_ErrorNone)
7134 {
7135 DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
7136 omx_report_error ();
7137 break;
7138 }
7139 }
7140
7141 return ret;
7142}
7143
7144OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
7145{
7146 OMX_U32 partial_frame = 1;
7147 OMX_BOOL generate_ebd = OMX_TRUE;
7148 unsigned address,p2,id;
7149
7150 DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %d",
7151 psource_frame,psource_frame->nTimeStamp);
7152 if (m_frame_parser.parse_sc_frame(psource_frame,
7153 pdest_frame,&partial_frame) == -1)
7154 {
7155 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7156 return OMX_ErrorBadParameter;
7157 }
7158
7159 if (partial_frame == 0)
7160 {
7161 DEBUG_PRINT_LOW("\n Frame size %d source %p frame count %d",
7162 pdest_frame->nFilledLen,psource_frame,frame_count);
7163
7164
7165 DEBUG_PRINT_LOW("\n TimeStamp updated %d",pdest_frame->nTimeStamp);
7166 /*First Parsed buffer will have only header Hence skip*/
7167 if (frame_count == 0)
7168 {
7169 DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
7170
7171 if(codec_type_parse == CODEC_TYPE_MPEG4 ||
7172 codec_type_parse == CODEC_TYPE_DIVX) {
7173 mp4StreamType psBits;
7174 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
7175 psBits.numBytes = pdest_frame->nFilledLen;
7176 mp4_headerparser.parseHeader(&psBits);
7177 }
7178
7179 frame_count++;
7180 }
7181 else
7182 {
7183 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7184 if(pdest_frame->nFilledLen)
7185 {
7186 /*Push the frame to the Decoder*/
7187 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7188 {
7189 return OMX_ErrorBadParameter;
7190 }
7191 frame_count++;
7192 pdest_frame = NULL;
7193
7194 if (m_input_free_q.m_size)
7195 {
7196 m_input_free_q.pop_entry(&address,&p2,&id);
7197 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7198 pdest_frame->nFilledLen = 0;
7199 }
7200 }
7201 else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS))
7202 {
7203 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
7204 m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
7205 pdest_frame = NULL;
7206 }
7207 }
7208 }
7209 else
7210 {
7211 DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen);
7212 /*Check if Destination Buffer is full*/
7213 if (pdest_frame->nAllocLen ==
7214 pdest_frame->nFilledLen + pdest_frame->nOffset)
7215 {
7216 DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
7217 return OMX_ErrorStreamCorrupt;
7218 }
7219 }
7220
7221 if (psource_frame->nFilledLen == 0)
7222 {
7223 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7224 {
7225 if (pdest_frame)
7226 {
7227 pdest_frame->nFlags |= psource_frame->nFlags;
7228 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
7229 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7230 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
7231 pdest_frame->nFilledLen,frame_count++);
7232 /*Push the frame to the Decoder*/
7233 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7234 {
7235 return OMX_ErrorBadParameter;
7236 }
7237 frame_count++;
7238 pdest_frame = NULL;
7239 }
7240 else
7241 {
7242 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
7243 generate_ebd = OMX_FALSE;
7244 }
7245 }
7246 if(generate_ebd)
7247 {
7248 DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
7249 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7250 psource_frame = NULL;
7251
7252 if (m_input_pending_q.m_size)
7253 {
7254 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7255 m_input_pending_q.pop_entry(&address,&p2,&id);
7256 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7257 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
7258 psource_frame->nTimeStamp);
7259 DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
7260 psource_frame->nFlags,psource_frame->nFilledLen);
7261 }
7262 }
7263 }
7264 return OMX_ErrorNone;
7265}
7266
7267OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
7268{
7269 OMX_U32 partial_frame = 1;
7270 unsigned address,p2,id;
7271 OMX_BOOL isNewFrame = OMX_FALSE;
7272 OMX_BOOL generate_ebd = OMX_TRUE;
7273
7274 if (h264_scratch.pBuffer == NULL)
7275 {
7276 DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
7277 return OMX_ErrorBadParameter;
7278 }
7279 DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %d "
7280 "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
7281 DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
7282 if (h264_scratch.nFilledLen && look_ahead_nal)
7283 {
7284 look_ahead_nal = false;
7285 if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7286 h264_scratch.nFilledLen)
7287 {
7288 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7289 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7290 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7291 DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
7292 h264_scratch.nFilledLen = 0;
7293 }
7294 else
7295 {
7296 DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
7297 return OMX_ErrorBadParameter;
7298 }
7299 }
7300 if (nal_length == 0)
7301 {
7302 DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
7303 if (m_frame_parser.parse_sc_frame(psource_frame,
7304 &h264_scratch,&partial_frame) == -1)
7305 {
7306 DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
7307 return OMX_ErrorBadParameter;
7308 }
7309 }
7310 else
7311 {
7312 DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
7313 if (m_frame_parser.parse_h264_nallength(psource_frame,
7314 &h264_scratch,&partial_frame) == -1)
7315 {
7316 DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
7317 return OMX_ErrorBadParameter;
7318 }
7319 }
7320
7321 if (partial_frame == 0)
7322 {
7323 if (nal_count == 0 && h264_scratch.nFilledLen == 0)
7324 {
7325 DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
7326 nal_count++;
7327 h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7328 h264_scratch.nFlags = psource_frame->nFlags;
7329 }
7330 else
7331 {
7332 DEBUG_PRINT_LOW("\n Parsed New NAL Length = %d",h264_scratch.nFilledLen);
7333 if(h264_scratch.nFilledLen)
7334 {
7335 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7336 NALU_TYPE_SPS);
7337#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7338 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7339 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7340 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7341 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7342 // If timeinfo is present frame info from SEI is already processed
7343 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7344 h264_scratch.nFilledLen, NALU_TYPE_SEI);
7345#endif
7346 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7347 nal_count++;
7348 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7349 pdest_frame->nTimeStamp = h264_last_au_ts;
7350 pdest_frame->nFlags = h264_last_au_flags;
7351#ifdef PANSCAN_HDLR
7352 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7353 h264_parser->update_panscan_data(h264_last_au_ts);
7354#endif
7355 }
7356 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7357 m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7358 h264_last_au_ts = h264_scratch.nTimeStamp;
7359 h264_last_au_flags = h264_scratch.nFlags;
7360#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7361 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7362 {
7363 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7364 if (!VALID_TS(h264_last_au_ts))
7365 h264_last_au_ts = ts_in_sei;
7366 }
7367#endif
7368 } else
7369 h264_last_au_ts = LLONG_MAX;
7370 }
7371
7372 if (!isNewFrame)
7373 {
7374 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7375 h264_scratch.nFilledLen)
7376 {
7377 DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %d",
7378 h264_scratch.nFilledLen);
7379 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7380 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7381 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7382 if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7383 pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7384 h264_scratch.nFilledLen = 0;
7385 }
7386 else
7387 {
7388 DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
7389 return OMX_ErrorBadParameter;
7390 }
7391 }
7392 else
7393 {
7394 look_ahead_nal = true;
7395 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
7396 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7397 DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
7398 pdest_frame->nFilledLen,frame_count++);
7399
7400 if (pdest_frame->nFilledLen == 0)
7401 {
7402 DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
7403 look_ahead_nal = false;
7404 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7405 h264_scratch.nFilledLen)
7406 {
7407 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7408 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7409 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7410 h264_scratch.nFilledLen = 0;
7411 }
7412 else
7413 {
7414 DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7415 return OMX_ErrorBadParameter;
7416 }
7417 }
7418 else
7419 {
7420 if(psource_frame->nFilledLen || h264_scratch.nFilledLen)
7421 {
7422 DEBUG_PRINT_LOW("\n Reset the EOS Flag");
7423 pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7424 }
7425 /*Push the frame to the Decoder*/
7426 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7427 {
7428 return OMX_ErrorBadParameter;
7429 }
7430 //frame_count++;
7431 pdest_frame = NULL;
7432 if (m_input_free_q.m_size)
7433 {
7434 m_input_free_q.pop_entry(&address,&p2,&id);
7435 pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7436 DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
7437 pdest_frame->nFilledLen = 0;
7438 pdest_frame->nFlags = 0;
7439 pdest_frame->nTimeStamp = LLONG_MAX;
7440 }
7441 }
7442 }
7443 }
7444 }
7445 else
7446 {
7447 DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
7448 /*Check if Destination Buffer is full*/
7449 if (h264_scratch.nAllocLen ==
7450 h264_scratch.nFilledLen + h264_scratch.nOffset)
7451 {
7452 DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7453 return OMX_ErrorStreamCorrupt;
7454 }
7455 }
7456
7457 if (!psource_frame->nFilledLen)
7458 {
7459 DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
7460
7461 if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)
7462 {
7463 if (pdest_frame)
7464 {
7465 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
7466 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7467 h264_scratch.nFilledLen)
7468 {
7469 memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7470 h264_scratch.pBuffer,h264_scratch.nFilledLen);
7471 pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7472 h264_scratch.nFilledLen = 0;
7473 }
7474 else
7475 {
7476 DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7477 return OMX_ErrorBadParameter;
7478 }
7479 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7480 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7481
7482 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%d TimeStamp = %x",
7483 pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7484 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
7485#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7486 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7487 {
7488 OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7489 if (!VALID_TS(pdest_frame->nTimeStamp))
7490 pdest_frame->nTimeStamp = ts_in_sei;
7491 }
7492#endif
7493 /*Push the frame to the Decoder*/
7494 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
7495 {
7496 return OMX_ErrorBadParameter;
7497 }
7498 frame_count++;
7499 pdest_frame = NULL;
7500 }
7501 else
7502 {
7503 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d",
7504 pdest_frame,h264_scratch.nFilledLen);
7505 generate_ebd = OMX_FALSE;
7506 }
7507 }
7508 }
7509 if(generate_ebd && !psource_frame->nFilledLen)
7510 {
7511 m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7512 psource_frame = NULL;
7513 if (m_input_pending_q.m_size)
7514 {
7515 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
7516 m_input_pending_q.pop_entry(&address,&p2,&id);
7517 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7518 DEBUG_PRINT_LOW("\nNext source Buffer flag %d src length %d",
7519 psource_frame->nFlags,psource_frame->nFilledLen);
7520 }
7521 }
7522 return OMX_ErrorNone;
7523}
7524
7525OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7526{
7527 OMX_U8 *buf, *pdest;
7528 OMX_U32 partial_frame = 1;
7529 OMX_U32 buf_len, dest_len;
7530
7531 if(first_frame == 0)
7532 {
7533 first_frame = 1;
7534 DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
7535 if(!m_vendor_config.pData)
7536 {
7537 DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
7538 buf = psource_frame->pBuffer;
7539 buf_len = psource_frame->nFilledLen;
7540
7541 if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7542 VC1_SP_MP_START_CODE)
7543 {
7544 m_vc1_profile = VC1_SP_MP_RCV;
7545 }
7546 else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
7547 {
7548 m_vc1_profile = VC1_AP;
7549 }
7550 else
7551 {
7552 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
7553 return OMX_ErrorStreamCorrupt;
7554 }
7555 }
7556 else
7557 {
7558 pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7559 pdest_frame->nOffset;
7560 dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7561 pdest_frame->nOffset);
7562
7563 if(dest_len < m_vendor_config.nDataSize)
7564 {
7565 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
7566 return OMX_ErrorBadParameter;
7567 }
7568 else
7569 {
7570 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7571 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7572 }
7573 }
7574 }
7575
7576 switch(m_vc1_profile)
7577 {
7578 case VC1_AP:
7579 DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
7580 if (push_input_sc_codec(hComp) != OMX_ErrorNone)
7581 {
7582 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7583 return OMX_ErrorBadParameter;
7584 }
7585 break;
7586
7587 case VC1_SP_MP_RCV:
7588 default:
7589 DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
7590 return OMX_ErrorBadParameter;
7591 }
7592 return OMX_ErrorNone;
7593}
7594
7595bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7596 OMX_U32 alignment)
7597{
7598 struct pmem_allocation allocation;
7599 allocation.size = buffer_size;
7600 allocation.align = clip2(alignment);
7601 if (allocation.align < 4096)
7602 {
7603 allocation.align = 4096;
7604 }
7605 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
7606 {
7607 DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7608 allocation.align, allocation.size);
7609 return false;
7610 }
7611 return true;
7612}
7613#ifdef USE_ION
7614int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7615 OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7616 struct ion_fd_data *fd_data, int flag)
7617{
7618 int fd = -EINVAL;
7619 int rc = -EINVAL;
7620 int ion_dev_flag;
7621 struct vdec_ion ion_buf_info;
7622 if (!alloc_data || buffer_size <= 0 || !fd_data) {
7623 DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7624 return -EINVAL;
7625 }
Arun Menon737de532012-09-14 14:48:18 -07007626 ion_dev_flag = O_RDONLY;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007627 fd = open (MEM_DEVICE, ion_dev_flag);
7628 if (fd < 0) {
7629 DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7630 return fd;
7631 }
Arun Menon737de532012-09-14 14:48:18 -07007632 alloc_data->flags = 0;
7633 if(!secure_mode && (flag & ION_FLAG_CACHED))
7634 {
7635 alloc_data->flags |= ION_FLAG_CACHED;
7636 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007637 alloc_data->len = buffer_size;
7638 alloc_data->align = clip2(alignment);
7639 if (alloc_data->align < 4096)
7640 {
7641 alloc_data->align = 4096;
7642 }
Vinay Kalia53fa6832012-10-11 17:55:30 -07007643 if ((secure_mode) && (flag & ION_SECURE))
7644 alloc_data->flags |= ION_SECURE;
7645
7646 alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
Vinay Kalia14c26132012-12-07 15:18:14 -08007647 if (!secure_mode)
7648 alloc_data->heap_mask |= ION_HEAP(ION_IOMMU_HEAP_ID);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007649 rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7650 if (rc || !alloc_data->handle) {
7651 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7652 alloc_data->handle = NULL;
7653 close(fd);
7654 fd = -ENOMEM;
7655 return fd;
7656 }
7657 fd_data->handle = alloc_data->handle;
7658 rc = ioctl(fd,ION_IOC_MAP,fd_data);
7659 if (rc) {
7660 DEBUG_PRINT_ERROR("\n ION MAP failed ");
7661 ion_buf_info.ion_alloc_data = *alloc_data;
7662 ion_buf_info.ion_device_fd = fd;
7663 ion_buf_info.fd_ion_data = *fd_data;
7664 free_ion_memory(&ion_buf_info);
7665 fd_data->fd =-1;
7666 close(fd);
7667 fd = -ENOMEM;
7668 }
7669
7670 return fd;
7671}
7672
7673void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) {
7674
7675 if(!buf_ion_info) {
7676 DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7677 return;
7678 }
7679 if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7680 &buf_ion_info->ion_alloc_data.handle)) {
7681 DEBUG_PRINT_ERROR("\n ION: free failed" );
7682 }
7683 close(buf_ion_info->ion_device_fd);
7684 buf_ion_info->ion_device_fd = -1;
7685 buf_ion_info->ion_alloc_data.handle = NULL;
7686 buf_ion_info->fd_ion_data.fd = -1;
7687}
7688#endif
7689void omx_vdec::free_output_buffer_header()
7690{
7691 DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
7692 output_use_buffer = false;
7693 ouput_egl_buffers = false;
7694
7695 if (m_out_mem_ptr)
7696 {
7697 free (m_out_mem_ptr);
7698 m_out_mem_ptr = NULL;
7699 }
7700
7701 if(m_platform_list)
7702 {
7703 free(m_platform_list);
7704 m_platform_list = NULL;
7705 }
7706
7707 if (drv_ctx.ptr_respbuffer)
7708 {
7709 free (drv_ctx.ptr_respbuffer);
7710 drv_ctx.ptr_respbuffer = NULL;
7711 }
7712 if (drv_ctx.ptr_outputbuffer)
7713 {
7714 free (drv_ctx.ptr_outputbuffer);
7715 drv_ctx.ptr_outputbuffer = NULL;
7716 }
7717#ifdef USE_ION
7718 if (drv_ctx.op_buf_ion_info) {
7719 DEBUG_PRINT_LOW("\n Free o/p ion context");
7720 free(drv_ctx.op_buf_ion_info);
7721 drv_ctx.op_buf_ion_info = NULL;
7722 }
7723#endif
7724}
7725
7726void omx_vdec::free_input_buffer_header()
7727{
7728 input_use_buffer = false;
7729 if (arbitrary_bytes)
7730 {
7731 if (m_frame_parser.mutils)
7732 {
7733 DEBUG_PRINT_LOW("\n Free utils parser");
7734 delete (m_frame_parser.mutils);
7735 m_frame_parser.mutils = NULL;
7736 }
7737
7738 if (m_inp_heap_ptr)
7739 {
7740 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
7741 free (m_inp_heap_ptr);
7742 m_inp_heap_ptr = NULL;
7743 }
7744
7745 if (m_phdr_pmem_ptr)
7746 {
7747 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
7748 free (m_phdr_pmem_ptr);
7749 m_phdr_pmem_ptr = NULL;
7750 }
7751 }
7752 if (m_inp_mem_ptr)
7753 {
7754 DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
7755 free (m_inp_mem_ptr);
7756 m_inp_mem_ptr = NULL;
7757 }
7758 if (drv_ctx.ptr_inputbuffer)
7759 {
7760 DEBUG_PRINT_LOW("\n Free Driver Context pointer");
7761 free (drv_ctx.ptr_inputbuffer);
7762 drv_ctx.ptr_inputbuffer = NULL;
7763 }
7764#ifdef USE_ION
7765 if (drv_ctx.ip_buf_ion_info) {
7766 DEBUG_PRINT_LOW("\n Free ion context");
7767 free(drv_ctx.ip_buf_ion_info);
7768 drv_ctx.ip_buf_ion_info = NULL;
7769 }
7770#endif
7771}
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007772
7773int omx_vdec::stream_off(OMX_U32 port)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007774{
Shalaj Jain273b3e02012-06-22 19:08:03 -07007775 enum v4l2_buf_type btype;
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007776 int rc = 0;
7777 enum v4l2_ports v4l2_port;
7778
7779 if (port == OMX_CORE_INPUT_PORT_INDEX) {
7780 btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7781 v4l2_port = OUTPUT_PORT;
7782 } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
7783 btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7784 v4l2_port = CAPTURE_PORT;
7785 } else if (port == OMX_ALL) {
7786 int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
7787 int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
7788
7789 if (!rc_input)
7790 return rc_input;
7791 else
7792 return rc_output;
7793 }
7794
7795 if (!streaming[v4l2_port]) {
7796 // already streamed off, warn and move on
7797 DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
7798 " which is already streamed off", v4l2_port);
7799 return 0;
7800 }
7801
7802 DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
7803
Shalaj Jain273b3e02012-06-22 19:08:03 -07007804 rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
7805 if (rc) {
7806 /*TODO: How to handle this case */
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007807 DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007808 } else {
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007809 streaming[v4l2_port] = false;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007810 }
Deva Ramasubramanianf97488b2012-10-26 18:37:05 -07007811
7812 return rc;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007813}
7814
7815OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7816{
7817 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7818 struct v4l2_requestbuffers bufreq;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007819 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007820 struct v4l2_format fmt;
7821 int ret;
7822 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7823 buffer_prop->actualcount, buffer_prop->buffer_size);
7824 bufreq.memory = V4L2_MEMORY_USERPTR;
Praneeth Paladugue3337f62012-10-16 17:35:59 -07007825 bufreq.count = 1;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007826 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7827 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7828 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7829 fmt.fmt.pix_mp.pixelformat = output_capability;
7830 }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){
7831 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7832 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7833 fmt.fmt.pix_mp.pixelformat = capture_capability;
7834 }else {eRet = OMX_ErrorBadParameter;}
7835 if(eRet==OMX_ErrorNone){
7836 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7837 }
7838 if(ret)
7839 {
7840 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7841 /*TODO: How to handle this case */
7842 eRet = OMX_ErrorInsufficientResources;
7843 return eRet;
7844 }
7845 else
7846 {
7847 buffer_prop->actualcount = bufreq.count;
7848 buffer_prop->mincount = bufreq.count;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007849 DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007850 }
7851 DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7852 buffer_prop->actualcount, buffer_prop->buffer_size);
7853
7854 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7855 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
7856
7857 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
7858
Vinay Kalia592e4b42012-12-19 15:55:47 -08007859 update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height);
Vinay Kalia5713bb32013-01-16 18:39:59 -08007860 if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
7861 drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
Ashray Kulkarni46373df2012-06-05 20:11:31 -07007862 DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007863
7864 if(ret)
7865 {
7866 /*TODO: How to handle this case */
7867 DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7868 eRet = OMX_ErrorInsufficientResources;
7869 }
7870 else
7871 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007872 int extra_idx = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007873 buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
7874 buf_size = buffer_prop->buffer_size;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007875 extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
7876 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
7877 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
7878 } else if (extra_idx >= VIDEO_MAX_PLANES) {
7879 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
7880 return OMX_ErrorBadParameter;
7881 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007882 if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7883 {
7884 DEBUG_PRINT_HIGH("Frame info extra data enabled!");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007885 client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007886 }
7887 if (client_extradata & OMX_INTERLACE_EXTRADATA)
7888 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007889 client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007890 }
7891 if (client_extradata & OMX_PORTDEF_EXTRADATA)
7892 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007893 client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7894 DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
7895 client_extra_data_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007896 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007897 if (client_extra_data_size)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007898 {
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007899 client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
Shalaj Jain273b3e02012-06-22 19:08:03 -07007900 buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7901 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007902 drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
7903 drv_ctx.extradata_info.count = buffer_prop->actualcount;
7904 drv_ctx.extradata_info.buffer_size = extra_data_size;
7905 buf_size += client_extra_data_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007906 buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7907 DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07007908 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007909 if (in_reconfig) // BufReq will be set to driver when port is disabled
7910 buffer_prop->buffer_size = buf_size;
7911 else if (buf_size != buffer_prop->buffer_size)
7912 {
7913 buffer_prop->buffer_size = buf_size;
7914 eRet = set_buffer_req(buffer_prop);
7915 }
7916 }
7917 DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7918 buffer_prop->actualcount, buffer_prop->buffer_size);
7919 return eRet;
7920}
7921
7922OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7923{
7924 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7925 unsigned buf_size = 0;
7926 struct v4l2_format fmt;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007927 struct v4l2_requestbuffers bufreq;
Shalaj Jain273b3e02012-06-22 19:08:03 -07007928 int ret;
7929 DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7930 buffer_prop->actualcount, buffer_prop->buffer_size);
7931 buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7932 if (buf_size != buffer_prop->buffer_size)
7933 {
7934 DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7935 buffer_prop->buffer_size, buf_size);
7936 eRet = OMX_ErrorBadParameter;
7937 }
7938 else
7939 {
7940 fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
7941 fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007942
7943 if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){
7944 fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7945 fmt.fmt.pix_mp.pixelformat = output_capability;
7946 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7947 fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7948 fmt.fmt.pix_mp.pixelformat = capture_capability;
7949 } else {eRet = OMX_ErrorBadParameter;}
7950
7951 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
7952 if (ret)
Shalaj Jain273b3e02012-06-22 19:08:03 -07007953 {
7954 /*TODO: How to handle this case */
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007955 DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
Shalaj Jain273b3e02012-06-22 19:08:03 -07007956 eRet = OMX_ErrorInsufficientResources;
7957 }
Deva Ramasubramanian614f79e2012-08-10 21:42:10 -07007958
7959 bufreq.memory = V4L2_MEMORY_USERPTR;
7960 bufreq.count = buffer_prop->actualcount;
7961 if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
7962 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
7963 } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
7964 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
7965 } else {eRet = OMX_ErrorBadParameter;}
7966
7967 if (eRet==OMX_ErrorNone) {
7968 ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
7969 }
7970
7971 if (ret)
7972 {
7973 DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
7974 /*TODO: How to handle this case */
7975 eRet = OMX_ErrorInsufficientResources;
7976 } else if (bufreq.count < buffer_prop->actualcount) {
7977 DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
7978 " on v4l2 port %d to %d (prefers %d)", bufreq.type,
7979 buffer_prop->actualcount, bufreq.count);
7980 eRet = OMX_ErrorInsufficientResources;
Vinay Kaliada4f4422013-01-09 10:45:03 -08007981 } else {
7982 if (!client_buffers.update_buffer_req()) {
7983 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7984 eRet = OMX_ErrorInsufficientResources;
7985 }
7986 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07007987 }
7988 return eRet;
7989}
7990
Shalaj Jain273b3e02012-06-22 19:08:03 -07007991OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7992{
7993 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
7994 OMX_ERRORTYPE eRet = OMX_ErrorNone;
7995 ioctl_msg.in = NULL;
7996 ioctl_msg.out = &drv_ctx.video_resolution;
7997 if (/*ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_PICRES, &ioctl_msg)*/0)
7998 {
7999 DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_PICRES");
8000 eRet = OMX_ErrorHardware;
8001 }
8002 return eRet;
8003}
8004
8005OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
8006{
8007 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8008 if (!portDefn)
8009 {
8010 return OMX_ErrorBadParameter;
8011 }
8012 DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
8013 portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
8014 portDefn->nSize = sizeof(portDefn);
8015 portDefn->eDomain = OMX_PortDomainVideo;
8016 if (drv_ctx.frame_rate.fps_denominator > 0)
8017 portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
8018 drv_ctx.frame_rate.fps_denominator;
8019 else {
8020 DEBUG_PRINT_ERROR("Error: Divide by zero \n");
8021 return OMX_ErrorBadParameter;
8022 }
8023 if (0 == portDefn->nPortIndex)
8024 {
8025 portDefn->eDir = OMX_DirInput;
8026 portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
8027 portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount;
8028 portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size;
8029 portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
8030 portDefn->format.video.eCompressionFormat = eCompressionFormat;
8031 portDefn->bEnabled = m_inp_bEnabled;
8032 portDefn->bPopulated = m_inp_bPopulated;
8033 }
8034 else if (1 == portDefn->nPortIndex)
8035 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008036 unsigned int buf_size = 0;
8037 if (!client_buffers.update_buffer_req()) {
8038 DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
8039 return OMX_ErrorHardware;
8040 }
8041 if (!client_buffers.get_buffer_req(buf_size)) {
8042 DEBUG_PRINT_ERROR("\n update buffer requirements");
8043 return OMX_ErrorHardware;
8044 }
8045 portDefn->nBufferSize = buf_size;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008046 portDefn->eDir = OMX_DirOutput;
Vinay Kaliafeef7032012-09-25 19:23:33 -07008047 portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
8048 portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008049 portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
8050 portDefn->bEnabled = m_out_bEnabled;
8051 portDefn->bPopulated = m_out_bPopulated;
Vinay Kaliada4f4422013-01-09 10:45:03 -08008052 if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
8053 DEBUG_PRINT_ERROR("\n Error in getting color format");
8054 return OMX_ErrorHardware;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008055 }
8056 }
8057 else
8058 {
Vinay Kaliada4f4422013-01-09 10:45:03 -08008059 portDefn->eDir = OMX_DirMax;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008060 DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
8061 (int)portDefn->nPortIndex);
8062 eRet = OMX_ErrorBadPortIndex;
8063 }
8064 portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height;
8065 portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width;
8066 portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
8067 portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
Vinay Kaliada8f3cf2012-12-21 18:26:21 -08008068 DEBUG_PRINT_ERROR("update_portdef Width = %d Height = %d Stride = %u"
8069 " SliceHeight = %u \n", portDefn->format.video.nFrameWidth,
8070 portDefn->format.video.nFrameHeight,
Shalaj Jain273b3e02012-06-22 19:08:03 -07008071 portDefn->format.video.nStride,
8072 portDefn->format.video.nSliceHeight);
8073 return eRet;
8074
8075}
8076
8077OMX_ERRORTYPE omx_vdec::allocate_output_headers()
8078{
8079 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8080 OMX_BUFFERHEADERTYPE *bufHdr = NULL;
8081 unsigned i= 0;
8082
8083 if(!m_out_mem_ptr) {
8084 DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
8085 int nBufHdrSize = 0;
8086 int nPlatformEntrySize = 0;
8087 int nPlatformListSize = 0;
8088 int nPMEMInfoSize = 0;
8089 OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList;
8090 OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry;
8091 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
8092
8093 DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
8094 drv_ctx.op_buf.actualcount);
8095 nBufHdrSize = drv_ctx.op_buf.actualcount *
8096 sizeof(OMX_BUFFERHEADERTYPE);
8097
8098 nPMEMInfoSize = drv_ctx.op_buf.actualcount *
8099 sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
8100 nPlatformListSize = drv_ctx.op_buf.actualcount *
8101 sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
8102 nPlatformEntrySize = drv_ctx.op_buf.actualcount *
8103 sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
8104
8105 DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
8106 sizeof(OMX_BUFFERHEADERTYPE),
8107 nPMEMInfoSize,
8108 nPlatformListSize);
8109 DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
8110 m_out_bm_count);
8111 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
8112 // Alloc mem for platform specific info
8113 char *pPtr=NULL;
8114 pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
8115 nPMEMInfoSize,1);
8116 drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
8117 calloc (sizeof(struct vdec_bufferpayload),
8118 drv_ctx.op_buf.actualcount);
8119 drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\
8120 calloc (sizeof (struct vdec_output_frameinfo),
8121 drv_ctx.op_buf.actualcount);
8122#ifdef USE_ION
8123 drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
8124 calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
8125#endif
8126
8127 if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
8128 && drv_ctx.ptr_respbuffer)
8129 {
8130 bufHdr = m_out_mem_ptr;
8131 m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
8132 m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
8133 (((char *) m_platform_list) + nPlatformListSize);
8134 m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
8135 (((char *) m_platform_entry) + nPlatformEntrySize);
8136 pPlatformList = m_platform_list;
8137 pPlatformEntry = m_platform_entry;
8138 pPMEMInfo = m_pmem_info;
8139
8140 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
8141
8142 // Settting the entire storage nicely
8143 DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
8144 m_out_mem_ptr,pPlatformEntry);
8145 DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
8146 for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
8147 {
8148 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
8149 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
8150 // Set the values when we determine the right HxW param
8151 bufHdr->nAllocLen = 0;
8152 bufHdr->nFilledLen = 0;
8153 bufHdr->pAppPrivate = NULL;
8154 bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8155 pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
8156 pPlatformEntry->entry = pPMEMInfo;
8157 // Initialize the Platform List
8158 pPlatformList->nEntries = 1;
8159 pPlatformList->entryList = pPlatformEntry;
8160 // Keep pBuffer NULL till vdec is opened
8161 bufHdr->pBuffer = NULL;
8162 pPMEMInfo->offset = 0;
8163 pPMEMInfo->pmem_fd = 0;
8164 bufHdr->pPlatformPrivate = pPlatformList;
8165 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
8166#ifdef USE_ION
8167 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
8168#endif
8169 /*Create a mapping between buffers*/
8170 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
8171 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
8172 &drv_ctx.ptr_outputbuffer[i];
8173 // Move the buffer and buffer header pointers
8174 bufHdr++;
8175 pPMEMInfo++;
8176 pPlatformEntry++;
8177 pPlatformList++;
8178 }
8179 }
8180 else
8181 {
8182 DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
8183 m_out_mem_ptr, pPtr);
8184 if(m_out_mem_ptr)
8185 {
8186 free(m_out_mem_ptr);
8187 m_out_mem_ptr = NULL;
8188 }
8189 if(pPtr)
8190 {
8191 free(pPtr);
8192 pPtr = NULL;
8193 }
8194 if(drv_ctx.ptr_outputbuffer)
8195 {
8196 free(drv_ctx.ptr_outputbuffer);
8197 drv_ctx.ptr_outputbuffer = NULL;
8198 }
8199 if(drv_ctx.ptr_respbuffer)
8200 {
8201 free(drv_ctx.ptr_respbuffer);
8202 drv_ctx.ptr_respbuffer = NULL;
8203 }
8204#ifdef USE_ION
8205 if (drv_ctx.op_buf_ion_info) {
8206 DEBUG_PRINT_LOW("\n Free o/p ion context");
8207 free(drv_ctx.op_buf_ion_info);
8208 drv_ctx.op_buf_ion_info = NULL;
8209 }
8210#endif
8211 eRet = OMX_ErrorInsufficientResources;
8212 }
8213 } else {
8214 eRet = OMX_ErrorInsufficientResources;
8215 }
8216 return eRet;
8217}
8218
8219void omx_vdec::complete_pending_buffer_done_cbs()
8220{
8221 unsigned p1;
8222 unsigned p2;
8223 unsigned ident;
8224 omx_cmd_queue tmp_q, pending_bd_q;
8225 pthread_mutex_lock(&m_lock);
8226 // pop all pending GENERATE FDB from ftb queue
8227 while (m_ftb_q.m_size)
8228 {
8229 m_ftb_q.pop_entry(&p1,&p2,&ident);
8230 if(ident == OMX_COMPONENT_GENERATE_FBD)
8231 {
8232 pending_bd_q.insert_entry(p1,p2,ident);
8233 }
8234 else
8235 {
8236 tmp_q.insert_entry(p1,p2,ident);
8237 }
8238 }
8239 //return all non GENERATE FDB to ftb queue
8240 while(tmp_q.m_size)
8241 {
8242 tmp_q.pop_entry(&p1,&p2,&ident);
8243 m_ftb_q.insert_entry(p1,p2,ident);
8244 }
8245 // pop all pending GENERATE EDB from etb queue
8246 while (m_etb_q.m_size)
8247 {
8248 m_etb_q.pop_entry(&p1,&p2,&ident);
8249 if(ident == OMX_COMPONENT_GENERATE_EBD)
8250 {
8251 pending_bd_q.insert_entry(p1,p2,ident);
8252 }
8253 else
8254 {
8255 tmp_q.insert_entry(p1,p2,ident);
8256 }
8257 }
8258 //return all non GENERATE FDB to etb queue
8259 while(tmp_q.m_size)
8260 {
8261 tmp_q.pop_entry(&p1,&p2,&ident);
8262 m_etb_q.insert_entry(p1,p2,ident);
8263 }
8264 pthread_mutex_unlock(&m_lock);
8265 // process all pending buffer dones
8266 while(pending_bd_q.m_size)
8267 {
8268 pending_bd_q.pop_entry(&p1,&p2,&ident);
8269 switch(ident)
8270 {
8271 case OMX_COMPONENT_GENERATE_EBD:
8272 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
8273 {
8274 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
8275 omx_report_error ();
8276 }
8277 break;
8278
8279 case OMX_COMPONENT_GENERATE_FBD:
8280 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
8281 {
8282 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
8283 omx_report_error ();
8284 }
8285 break;
8286 }
8287 }
8288}
8289
8290void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
8291{
8292 OMX_U32 new_frame_interval = 0;
8293 struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
8294 if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
8295 && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000))
8296 {
8297 new_frame_interval = (act_timestamp > prev_ts)?
8298 act_timestamp - prev_ts :
8299 prev_ts - act_timestamp;
8300 if (new_frame_interval < frm_int || frm_int == 0)
8301 {
8302 frm_int = new_frame_interval;
8303 if(frm_int)
8304 {
8305 drv_ctx.frame_rate.fps_numerator = 1e6;
8306 drv_ctx.frame_rate.fps_denominator = frm_int;
8307 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
8308 frm_int, drv_ctx.frame_rate.fps_numerator /
8309 (float)drv_ctx.frame_rate.fps_denominator);
8310 ioctl_msg.in = &drv_ctx.frame_rate;
8311 if (/*ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE,
8312 (void*)&ioctl_msg) < */0)
8313 {
8314 DEBUG_PRINT_ERROR("Setting frame rate failed");
8315 }
8316 }
8317 }
8318 }
8319 prev_ts = act_timestamp;
8320}
8321
8322void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
8323{
8324 if (rst_prev_ts && VALID_TS(act_timestamp))
8325 {
8326 prev_ts = act_timestamp;
8327 rst_prev_ts = false;
8328 }
8329 else if (VALID_TS(prev_ts))
8330 {
8331 bool codec_cond = (drv_ctx.timestamp_adjust)?
8332 (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
8333 (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
8334 (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
8335 if(frm_int > 0 && codec_cond)
8336 {
8337 DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
8338 act_timestamp = prev_ts + frm_int;
8339 DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
8340 prev_ts = act_timestamp;
8341 }
8342 else
8343 set_frame_rate(act_timestamp);
8344 }
8345 else if (frm_int > 0) // In this case the frame rate was set along
8346 { // with the port definition, start ts with 0
8347 act_timestamp = prev_ts = 0; // and correct if a valid ts is received.
8348 rst_prev_ts = true;
8349 }
8350}
8351
8352void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8353{
8354 OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
8355 OMX_U32 num_conceal_MB = 0;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008356 OMX_U32 frame_rate = 0;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008357 OMX_U32 consumed_len = 0;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008358 OMX_U32 num_MB_in_frame;
8359 OMX_U32 recovery_sei_flags = 1;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008360 int buf_index = p_buf_hdr - m_out_mem_ptr;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008361 struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008362 OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + p_buf_hdr->nOffset);
8363 if (!drv_ctx.extradata_info.uaddr) {
8364 return;
8365 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008366 p_extra = (OMX_OTHER_EXTRADATATYPE *)
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008367 ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
8368 char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
8369 if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
Shalaj Jain273b3e02012-06-22 19:08:03 -07008370 p_extra = NULL;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008371 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008372 if (data) {
8373 while((consumed_len < drv_ctx.extradata_info.buffer_size)
8374 && (data->eType != EXTRADATA_NONE)) {
8375 if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008376 DEBUG_PRINT_LOW("Invalid extra data size");
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008377 break;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008378 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008379 switch(data->eType) {
8380 case EXTRADATA_INTERLACE_VIDEO:
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008381 struct msm_vidc_interlace_payload *payload;
8382 payload = (struct msm_vidc_interlace_payload *)data->data;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008383 if (payload->format != INTERLACE_FRAME_PROGRESSIVE) {
8384 int enable = 1;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008385 OMX_U32 mbaff = 0;
8386 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8387 if ((payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
8388 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8389 else
8390 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8391 if(m_enable_android_native_buffers)
8392 setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008393 PP_PARAM_INTERLACED, (void*)&enable);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008394 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008395 if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
8396 append_interlace_extradata(p_extra, payload->format);
8397 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8398 }
8399 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008400 case EXTRADATA_FRAME_RATE:
8401 struct msm_vidc_framerate_payload *frame_rate_payload;
8402 frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
8403 frame_rate = frame_rate_payload->frame_rate;
8404 break;
8405 case EXTRADATA_TIMESTAMP:
8406 struct msm_vidc_ts_payload *time_stamp_payload;
8407 time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008408 p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
8409 p_buf_hdr->nTimeStamp |= (time_stamp_payload->timestamp_hi << 32);
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008410 break;
8411 case EXTRADATA_NUM_CONCEALED_MB:
8412 struct msm_vidc_concealmb_payload *conceal_mb_payload;
8413 conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
8414 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8415 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8416 num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
8417 break;
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008418 case EXTRADATA_ASPECT_RATIO:
8419 struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
8420 aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)data->data;
8421 ((struct vdec_output_frameinfo *)
8422 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
8423 ((struct vdec_output_frameinfo *)
8424 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
8425 break;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008426 case EXTRADATA_RECOVERY_POINT_SEI:
8427 struct msm_vidc_recoverysei_payload *recovery_sei_payload;
8428 recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
8429 recovery_sei_flags = recovery_sei_payload->flags;
8430 if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
8431 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008432 DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received\n");
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008433 }
8434 break;
8435 case EXTRADATA_PANSCAN_WINDOW:
8436 panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
8437 break;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008438 default:
8439 goto unrecognized_extradata;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008440 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008441 consumed_len += data->nSize;
8442 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008443 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008444 if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
Praneeth Paladugu6e5fcfb2012-12-14 08:48:48 -08008445 p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008446 append_frame_info_extradata(p_extra,
8447 num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008448 panscan_payload,&((struct vdec_output_frameinfo *)
8449 p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008450 }
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008451unrecognized_extradata:
8452 if(!secure_mode && client_extradata)
8453 append_terminator_extradata(p_extra);
8454 return;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008455}
8456
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008457OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
8458 bool is_internal, bool enable)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008459{
8460 OMX_ERRORTYPE ret = OMX_ErrorNone;
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008461 struct v4l2_control control;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008462 if(m_state != OMX_StateLoaded)
8463 {
8464 DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8465 return OMX_ErrorIncorrectStateOperation;
8466 }
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008467 DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%x] requested[%x] enable[%d], is_internal: %d\n",
8468 client_extradata, requested_extradata, enable, is_internal);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008469
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008470 if (!is_internal) {
8471 if (enable)
8472 client_extradata |= requested_extradata;
8473 else
8474 client_extradata = client_extradata & ~requested_extradata;
8475 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008476
8477 if (enable) {
8478 if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
8479 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8480 control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
8481 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8482 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
8483 " Quality of interlaced clips might be impacted.\n");
8484 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008485 } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8486 {
8487 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8488 control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
8489 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8490 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
8491 }
8492 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8493 control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
8494 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8495 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
8496 }
8497 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8498 control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
8499 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8500 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
8501 }
8502 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8503 control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
8504 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8505 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8506 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008507 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8508 control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
8509 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8510 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
8511 }
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008512 } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA)
8513 {
8514 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
8515 control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
8516 if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
8517 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
8518 }
Vinay Kaliadb90f8c2012-11-19 18:57:56 -08008519 }
8520 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008521 return ret;
8522}
8523
8524OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8525{
8526 OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8527 OMX_U8 *data_ptr = extra->data, data = 0;
8528 while (byte_count < extra->nDataSize)
8529 {
8530 data = *data_ptr;
8531 while (data)
8532 {
8533 num_MB += (data&0x01);
8534 data >>= 1;
8535 }
8536 data_ptr++;
8537 byte_count++;
8538 }
8539 num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8540 (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8541 return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8542}
8543
8544void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8545{
8546 if (!m_debug_extradata)
8547 return;
8548
8549 DEBUG_PRINT_HIGH(
8550 "============== Extra Data ==============\n"
8551 " Size: %u \n"
8552 " Version: %u \n"
8553 " PortIndex: %u \n"
8554 " Type: %x \n"
8555 " DataSize: %u \n",
8556 extra->nSize, extra->nVersion.nVersion,
8557 extra->nPortIndex, extra->eType, extra->nDataSize);
8558
8559 if (extra->eType == OMX_ExtraDataInterlaceFormat)
8560 {
8561 OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8562 DEBUG_PRINT_HIGH(
8563 "------ Interlace Format ------\n"
8564 " Size: %u \n"
8565 " Version: %u \n"
8566 " PortIndex: %u \n"
8567 " Is Interlace Format: %u \n"
8568 " Interlace Formats: %u \n"
8569 "=========== End of Interlace ===========\n",
8570 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8571 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8572 }
8573 else if (extra->eType == OMX_ExtraDataFrameInfo)
8574 {
8575 OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8576
8577 DEBUG_PRINT_HIGH(
8578 "-------- Frame Format --------\n"
8579 " Picture Type: %u \n"
8580 " Interlace Type: %u \n"
8581 " Pan Scan Total Frame Num: %u \n"
8582 " Concealed Macro Blocks: %u \n"
8583 " frame rate: %u \n"
8584 " Aspect Ratio X: %u \n"
8585 " Aspect Ratio Y: %u \n",
8586 fminfo->ePicType,
8587 fminfo->interlaceType,
8588 fminfo->panScan.numWindows,
8589 fminfo->nConcealedMacroblocks,
8590 fminfo->nFrameRate,
8591 fminfo->aspectRatio.aspectRatioX,
8592 fminfo->aspectRatio.aspectRatioY);
8593
8594 for (int i = 0; i < fminfo->panScan.numWindows; i++)
8595 {
8596 DEBUG_PRINT_HIGH(
8597 "------------------------------\n"
8598 " Pan Scan Frame Num: %d \n"
8599 " Rectangle x: %d \n"
8600 " Rectangle y: %d \n"
8601 " Rectangle dx: %d \n"
8602 " Rectangle dy: %d \n",
8603 i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8604 fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8605 }
8606
8607 DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8608 }
8609 else if (extra->eType == OMX_ExtraDataNone)
8610 {
8611 DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8612 }
8613 else
8614 {
8615 DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8616 }
8617}
8618
8619void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8620 OMX_U32 interlaced_format_type)
8621{
8622 OMX_STREAMINTERLACEFORMAT *interlace_format;
8623 OMX_U32 mbaff = 0;
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008624 if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
8625 return;
8626 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008627 extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8628 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8629 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8630 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8631 extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8632 interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8633 interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8634 interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8635 interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8636 mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
Vinay Kalia0e75e9a2012-09-27 15:41:53 -07008637 if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008638 {
8639 interlace_format->bInterlaceFormat = OMX_FALSE;
8640 interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8641 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8642 }
8643 else
8644 {
8645 interlace_format->bInterlaceFormat = OMX_TRUE;
8646 interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8647 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8648 }
8649 print_debug_extradata(extra);
8650}
8651
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008652void omx_vdec::fill_aspect_ratio_info(
8653 struct vdec_aspectratioinfo *aspect_ratio_info,
8654 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
8655{
8656 m_extradata = frame_info;
8657 m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8658 m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
8659 DEBUG_PRINT_LOW("aspectRatioX %d aspectRatioX %d", m_extradata->aspectRatio.aspectRatioX,
8660 m_extradata->aspectRatio.aspectRatioY);
8661}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008662
8663void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008664 OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008665 struct msm_vidc_panscan_window_payload *panscan_payload,
8666 struct vdec_aspectratioinfo *aspect_ratio_info)
Shalaj Jain273b3e02012-06-22 19:08:03 -07008667{
8668 OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008669 struct msm_vidc_panscan_window *panscan_window;
8670 if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
8671 return;
8672 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008673 extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8674 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8675 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8676 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8677 extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8678 frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8679 switch (picture_type)
8680 {
8681 case PICTURE_TYPE_I:
8682 frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8683 break;
8684 case PICTURE_TYPE_P:
8685 frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8686 break;
8687 case PICTURE_TYPE_B:
8688 frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8689 break;
8690 default:
8691 frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8692 }
8693 if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8694 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8695 else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8696 frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8697 else
8698 frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008699 memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
Shalaj Jain273b3e02012-06-22 19:08:03 -07008700 frame_info->nConcealedMacroblocks = num_conceal_mb;
8701 frame_info->nFrameRate = frame_rate;
Praneeth Paladugu48a9a8a2012-12-06 12:12:19 -08008702 frame_info->panScan.numWindows = 0;
8703 if(panscan_payload) {
8704 frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
8705 panscan_window = &panscan_payload->wnd[0];
8706 for (int i = 0; i < frame_info->panScan.numWindows; i++)
8707 {
8708 frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
8709 frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
8710 frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
8711 frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
8712 panscan_window++;
8713 }
8714 }
Praneeth Paladuguf3a492b2013-01-03 17:35:34 -08008715 fill_aspect_ratio_info(aspect_ratio_info, frame_info);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008716 print_debug_extradata(extra);
8717}
8718
8719void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8720{
8721 OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8722 extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8723 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8724 extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8725 extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8726 extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8727 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8728 *portDefn = m_port_def;
8729 DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u stride = %u"
8730 "sliceheight = %u \n",portDefn->format.video.nFrameHeight,
8731 portDefn->format.video.nFrameWidth,
8732 portDefn->format.video.nStride,
8733 portDefn->format.video.nSliceHeight);
8734}
8735
8736void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8737{
Vinay Kalia9c00cae2012-12-06 16:08:20 -08008738 if (!client_extradata) {
8739 return;
8740 }
Shalaj Jain273b3e02012-06-22 19:08:03 -07008741 extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8742 extra->nVersion.nVersion = OMX_SPEC_VERSION;
8743 extra->eType = OMX_ExtraDataNone;
8744 extra->nDataSize = 0;
8745 extra->data[0] = 0;
8746
8747 print_debug_extradata(extra);
8748}
8749
8750OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index)
8751{
8752 OMX_ERRORTYPE eRet = OMX_ErrorNone;
8753 if (index >= drv_ctx.ip_buf.actualcount)
8754 {
8755 DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8756 return OMX_ErrorInsufficientResources;
8757 }
8758 if (m_desc_buffer_ptr == NULL)
8759 {
8760 m_desc_buffer_ptr = (desc_buffer_hdr*) \
8761 calloc( (sizeof(desc_buffer_hdr)),
8762 drv_ctx.ip_buf.actualcount);
8763 if (m_desc_buffer_ptr == NULL)
8764 {
8765 DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8766 return OMX_ErrorInsufficientResources;
8767 }
8768 }
8769
8770 m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8771 if (m_desc_buffer_ptr[index].buf_addr == NULL)
8772 {
8773 DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8774 return OMX_ErrorInsufficientResources;
8775 }
8776
8777 return eRet;
8778}
8779
8780void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8781{
8782 DEBUG_PRINT_LOW("Inserting address offset (%d) at idx (%d)", address_offset,m_demux_entries);
8783 if (m_demux_entries < 8192)
8784 {
8785 m_demux_offsets[m_demux_entries++] = address_offset;
8786 }
8787 return;
8788}
8789
8790void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8791{
8792 OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8793 OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8794 OMX_U32 index = 0;
8795
8796 m_demux_entries = 0;
8797
8798 while (index < bytes_to_parse)
8799 {
8800 if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8801 (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8802 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8803 (buf[index+2] == 0x01)) )
8804 {
8805 //Found start code, insert address offset
8806 insert_demux_addr_offset(index);
8807 if (buf[index+2] == 0x01) // 3 byte start code
8808 index += 3;
8809 else //4 byte start code
8810 index += 4;
8811 }
8812 else
8813 index++;
8814 }
8815 DEBUG_PRINT_LOW("Extracted (%d) demux entry offsets",m_demux_entries);
8816 return;
8817}
8818
8819OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8820{
8821 //fix this, handle 3 byte start code, vc1 terminator entry
8822 OMX_U8 *p_demux_data = NULL;
8823 OMX_U32 desc_data = 0;
8824 OMX_U32 start_addr = 0;
8825 OMX_U32 nal_size = 0;
8826 OMX_U32 suffix_byte = 0;
8827 OMX_U32 demux_index = 0;
8828 OMX_U32 buffer_index = 0;
8829
8830 if (m_desc_buffer_ptr == NULL)
8831 {
8832 DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8833 return OMX_ErrorBadParameter;
8834 }
8835
8836 buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8837 if (buffer_index > drv_ctx.ip_buf.actualcount)
8838 {
8839 DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%d)", buffer_index);
8840 return OMX_ErrorBadParameter;
8841 }
8842
8843 p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8844
8845 if ( ((OMX_U8*)p_demux_data == NULL) ||
8846 ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE)
8847 {
8848 DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8849 return OMX_ErrorBadParameter;
8850 }
8851 else
8852 {
8853 for (; demux_index < m_demux_entries; demux_index++)
8854 {
8855 desc_data = 0;
8856 start_addr = m_demux_offsets[demux_index];
8857 if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01)
8858 {
8859 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8860 }
8861 else
8862 {
8863 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8864 }
8865 if (demux_index < (m_demux_entries - 1))
8866 {
8867 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8868 }
8869 else
8870 {
8871 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8872 }
8873 DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%x),nal_size(%d),demux_index(%d)",
8874 start_addr,
8875 suffix_byte,
8876 nal_size,
8877 demux_index);
8878 desc_data = (start_addr >> 3) << 1;
8879 desc_data |= (start_addr & 7) << 21;
8880 desc_data |= suffix_byte << 24;
8881
8882 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8883 memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8884 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8885 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8886
8887 p_demux_data += 16;
8888 }
8889 if (codec_type_parse == CODEC_TYPE_VC1)
8890 {
8891 DEBUG_PRINT_LOW("VC1 terminator entry");
8892 desc_data = 0;
8893 desc_data = 0x82 << 24;
8894 memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8895 memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8896 memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8897 memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8898 p_demux_data += 16;
8899 m_demux_entries++;
8900 }
8901 //Add zero word to indicate end of descriptors
8902 memset(p_demux_data, 0, sizeof(OMX_U32));
8903
8904 m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8905 DEBUG_PRINT_LOW("desc table data size=%d", m_desc_buffer_ptr[buffer_index].desc_data_size);
8906 }
8907 memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8908 m_demux_entries = 0;
8909 DEBUG_PRINT_LOW("Demux table complete!");
8910 return OMX_ErrorNone;
8911}
8912
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008913OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
Shalaj Jain273b3e02012-06-22 19:08:03 -07008914{
8915 OMX_ERRORTYPE err = OMX_ErrorNone;
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008916 iDivXDrmDecrypt = DivXDrmDecrypt::Create();
Shalaj Jain273b3e02012-06-22 19:08:03 -07008917 if (iDivXDrmDecrypt) {
Shalaj Jain273b3e02012-06-22 19:08:03 -07008918 OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
8919 if(err!=OMX_ErrorNone) {
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008920 DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
Shalaj Jain273b3e02012-06-22 19:08:03 -07008921 delete iDivXDrmDecrypt;
8922 iDivXDrmDecrypt = NULL;
8923 }
8924 }
8925 else {
8926 DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
Deva Ramasubramanian9403f022012-11-28 18:27:53 -08008927 err = OMX_ErrorUndefined;
Shalaj Jain273b3e02012-06-22 19:08:03 -07008928 }
8929 return err;
8930}
Shalaj Jain273b3e02012-06-22 19:08:03 -07008931
Vinay Kaliada4f4422013-01-09 10:45:03 -08008932omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
8933{
8934 enabled = false;
8935 omx = NULL;
8936 init_members();
8937 ColorFormat = OMX_COLOR_FormatMax;
8938}
8939
8940void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
8941{
8942 omx = reinterpret_cast<omx_vdec*>(client);
8943}
8944
8945void omx_vdec::allocate_color_convert_buf::init_members() {
8946 allocated_count = 0;
8947 buffer_size_req = 0;
8948 buffer_alignment_req = 0;
8949 memset(m_platform_list_client,0,sizeof(m_platform_list_client));
8950 memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
8951 memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
8952 memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
8953#ifdef USE_ION
8954 memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
8955#endif
8956 for (int i = 0; i < MAX_COUNT;i++)
8957 pmem_fd[i] = -1;
8958}
8959
8960omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() {
8961 c2d.destroy();
8962}
8963
8964bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
8965{
8966 bool status = true;
8967 unsigned int src_size = 0, destination_size = 0;
8968 OMX_COLOR_FORMATTYPE drv_color_format;
8969 if (!omx){
8970 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
8971 return false;
8972 }
8973 if (!enabled){
8974 DEBUG_PRINT_ERROR("\n No color conversion required");
8975 return status;
8976 }
8977 if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
8978 ColorFormat != OMX_COLOR_FormatYUV420Planar) {
8979 DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
8980 return false;
8981 }
8982 c2d.close();
8983 status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
8984 omx->drv_ctx.video_resolution.frame_width,
8985 NV12_128m,YCbCr420P);
8986 if (status) {
8987 status = c2d.get_buffer_size(C2D_INPUT,src_size);
8988 if (status)
8989 status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
8990 }
8991 if (status) {
8992 if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
8993 !destination_size) {
8994 DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
8995 "driver size %d destination size %d",
8996 src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
8997 status = false;
8998 c2d.close();
8999 buffer_size_req = 0;
9000 } else {
9001 buffer_size_req = destination_size;
9002 if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9003 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9004 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9005 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9006 }
9007 }
9008 return status;
9009}
9010
9011bool omx_vdec::allocate_color_convert_buf::set_color_format(
9012 OMX_COLOR_FORMATTYPE dest_color_format)
9013{
9014 bool status = true;
9015 OMX_COLOR_FORMATTYPE drv_color_format;
9016 if (!omx){
9017 DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9018 return false;
9019 }
9020 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9021 drv_color_format = (OMX_COLOR_FORMATTYPE)
9022 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9023 else {
9024 DEBUG_PRINT_ERROR("\n Incorrect color format");
9025 status = false;
9026 }
9027 if (status && (drv_color_format != dest_color_format)) {
9028 DEBUG_PRINT_LOW("Enabling C2D\n");
9029 if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
9030 DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
9031 status = false;
9032 } else {
9033 ColorFormat = OMX_COLOR_FormatYUV420Planar;
9034 if (enabled)
9035 c2d.destroy();
9036 enabled = false;
9037 if (!c2d.init()) {
9038 DEBUG_PRINT_ERROR("\n open failed for c2d");
9039 status = false;
9040 } else
9041 enabled = true;
9042 }
9043 } else {
9044 if (enabled)
9045 c2d.destroy();
9046 enabled = false;
9047 }
9048 return status;
9049}
9050
9051OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9052{
9053 if (!omx){
9054 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9055 return NULL;
9056 }
9057 if (!enabled)
9058 return omx->m_out_mem_ptr;
9059 return m_out_mem_ptr_client;
9060}
9061
9062OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9063 (OMX_BUFFERHEADERTYPE *bufadd)
9064{
9065 if (!omx){
9066 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9067 return NULL;
9068 }
9069 if (!enabled)
9070 return bufadd;
9071
9072 unsigned index = 0;
9073 index = bufadd - omx->m_out_mem_ptr;
9074 if (index < omx->drv_ctx.op_buf.actualcount) {
9075 m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9076 m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9077 bool status;
9078 if (!omx->in_reconfig && !omx->output_flush_progress) {
9079 status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9080 bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]);
9081 m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9082 if (!status){
9083 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
9084 return NULL;
9085 }
9086 } else
9087 m_out_mem_ptr_client[index].nFilledLen = 0;
9088 return &m_out_mem_ptr_client[index];
9089 }
9090 DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
9091 return NULL;
9092}
9093
9094OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9095 (OMX_BUFFERHEADERTYPE *bufadd)
9096{
9097 if (!omx){
9098 DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9099 return NULL;
9100 }
9101 if (!enabled)
9102 return bufadd;
9103 unsigned index = 0;
9104 index = bufadd - m_out_mem_ptr_client;
9105 if (index < omx->drv_ctx.op_buf.actualcount) {
9106 return &omx->m_out_mem_ptr[index];
9107 }
9108 DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
9109 return NULL;
9110}
9111bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9112 (unsigned int &buffer_size)
9113{
9114 if (!enabled)
9115 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9116 else
9117 if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
9118 DEBUG_PRINT_ERROR("\n Get buffer size failed");
9119 return false;
9120 }
9121 if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9122 buffer_size = omx->drv_ctx.op_buf.buffer_size;
9123 if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9124 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9125 return true;
9126}
9127OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
9128 OMX_BUFFERHEADERTYPE *bufhdr) {
9129 unsigned int index = 0;
9130
9131 if (!enabled)
9132 return omx->free_output_buffer(bufhdr);
9133 if (enabled && omx->is_component_secure())
9134 return OMX_ErrorNone;
9135 if (!allocated_count || !bufhdr) {
9136 DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
9137 return OMX_ErrorBadParameter;
9138 }
9139 index = bufhdr - m_out_mem_ptr_client;
9140 if (index >= omx->drv_ctx.op_buf.actualcount){
9141 DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
9142 return OMX_ErrorBadParameter;
9143 }
9144 if (pmem_fd[index] > 0) {
9145 munmap(pmem_baseaddress[index], buffer_size_req);
9146 close(pmem_fd[index]);
9147 }
9148 pmem_fd[index] = -1;
9149#ifdef USE_ION
9150 omx->free_ion_memory(&op_buf_ion_info[index]);
9151#endif
9152 m_heap_ptr[index].video_heap_ptr = NULL;
9153 if (allocated_count > 0)
9154 allocated_count--;
9155 else
9156 allocated_count = 0;
9157 if (!allocated_count) {
9158 c2d.close();
9159 init_members();
9160 }
9161 return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
9162}
9163
9164OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
9165 OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
9166{
9167 OMX_ERRORTYPE eRet = OMX_ErrorNone;
9168 if (!enabled){
9169 eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9170 return eRet;
9171 }
9172 if (enabled && omx->is_component_secure()) {
9173 DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
9174 omx->is_component_secure());
9175 return OMX_ErrorUnsupportedSetting;
9176 }
9177 if (!bufferHdr || bytes > buffer_size_req) {
9178 DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
9179 DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %d",
9180 buffer_size_req,bytes);
9181 return OMX_ErrorBadParameter;
9182 }
9183 if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
9184 DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
9185 return OMX_ErrorInsufficientResources;
9186 }
9187 OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9188 eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9189 port,appData,omx->drv_ctx.op_buf.buffer_size);
9190 if (eRet != OMX_ErrorNone || !temp_bufferHdr){
9191 DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
9192 return eRet;
9193 }
9194 if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
9195 omx->drv_ctx.op_buf.actualcount) {
9196 DEBUG_PRINT_ERROR("\n Invalid header index %d",
9197 (temp_bufferHdr - omx->m_out_mem_ptr));
9198 return OMX_ErrorUndefined;
9199 }
9200 unsigned int i = allocated_count;
9201#ifdef USE_ION
9202 op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9203 buffer_size_req,buffer_alignment_req,
9204 &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9205 ION_FLAG_CACHED);
9206 pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9207 if (op_buf_ion_info[i].ion_device_fd < 0) {
9208 DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
9209 return OMX_ErrorInsufficientResources;
9210 }
9211 pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9212 PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
9213
9214 if (pmem_baseaddress[i] == MAP_FAILED) {
9215 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
9216 close(pmem_fd[i]);
9217 omx->free_ion_memory(&op_buf_ion_info[i]);
9218 return OMX_ErrorInsufficientResources;
9219 }
9220 m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9221 op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9222 pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
9223#endif
9224 m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9225 m_pmem_info_client[i].offset = 0;
9226 m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9227 m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9228 m_platform_list_client[i].nEntries = 1;
9229 m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9230 m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9231 m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9232 m_out_mem_ptr_client[i].nFilledLen = 0;
9233 m_out_mem_ptr_client[i].nFlags = 0;
9234 m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9235 m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9236 m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9237 m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9238 m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9239 m_out_mem_ptr_client[i].pAppPrivate = appData;
9240 *bufferHdr = &m_out_mem_ptr_client[i];
9241 DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
9242 allocated_count++;
9243 return eRet;
9244}
9245
9246bool omx_vdec::is_component_secure()
9247{
9248 return secure_mode;
9249}
9250
9251bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9252{
9253 bool status = true;
9254 if (!enabled) {
9255 if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9256 dest_color_format = (OMX_COLOR_FORMATTYPE)
9257 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
9258 else
9259 status = false;
9260 } else {
9261 if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9262 status = false;
9263 } else
9264 dest_color_format = OMX_COLOR_FormatYUV420Planar;
9265 }
9266 return status;
9267}